Project Euler 78:Coin partitions
Let p(n) represent the number of different ways in which n coins can be separated into piles. For example, five coins can separated into piles in exactly seven different ways, so p(5)=7.
OOOOO
OOOO O
OOO OO
OOO O O
OO OO O
OO O O O
O O O O O
Find the least value of n for which p(n) is divisible by one million.
记p(n)是将n枚硬币分拆成堆的不同方式数。例如,五枚硬币有7种分拆成堆的不同方式,因此p(5)=7。
OOOOO
OOOO O
OOO OO
OOO O O
OO OO O
OO O O O
O O O O O
找出使p(n)能被一百万整除的最小n值。
思路:
求数的拆分有多少种
再判断是否能被一百万整除
参考资料:wiki ,PartitionFunctionP
法一:
根据这个等式:
高能预警:
1. 这里是两部分的和
2.当第一个不满足条件,即:n<k(3k-1)/2 时候,第二个一定不成立
3.第一个满足条件,第二个可能不满足条件,这里说的条件都是数组下标不能越界
4.满足条件的都要计算,只有当第一个不满足条件的时候才本次循环
5.前面的(-1)^(k+1),要乘进去,展开计算,就是计算符合条件的数组
关键程序:
for(k=1;k<=n;k++){
gk1 = k*(3*k-1)/2;
gk2 = gk1+k;
if(gk1>n) break;
plist.set(n,plist.get(n)+flag*plist.get(n-gk1));
if(gk2<=n){
plist.set(n,plist.get(n)+flag*plist.get(n-gk2));
}
plist.set(n,plist.get(n)%limit);
flag*=-1;
}
这里由于我只是在上面看到的求解表达式,造成我搞了好久都没有搞出来,没文化正可怕
法二:
看到这里还没有出问题
看到这里,直接根据上面的表达式求解了,然而这里的k不是从1-n,这里我又理解错了,以为拿来用就好了
上面的方法不行,下面的方法也不行,真是浪费了好多时间的
下面程序中有一个求k的过程,这里才是真谛啊!!!
关键程序:
while(gk<=n){
flag = (i%4>1)?-1:1;
plist.set(n,plist.get(n)+flag*plist.get(n-gk));
plist.set(n,plist.get(n)%limit);
i++;
int k= (i%2==0)?i/2+1:-(i/2+1);
gk = k*(3*k-1)/2;
}
Java程序:
package Level3; import java.util.ArrayList; public class PE078{ void run(){
int limit = 1000000;
partitions2(limit);
}
void partitions2(int limit){
ArrayList<Integer> plist = new ArrayList<Integer>();
plist.add(1);
int n = 1;
while(true){
int gk1 =1;
int gk2 =2;
int k=1;
plist.add(0);// 初始第n
int flag = 1;
for(k=1;k<=n;k++){
gk1 = k*(3*k-1)/2;
gk2 = gk1+k;
if(gk1>n) break;
plist.set(n,plist.get(n)+flag*plist.get(n-gk1));
if(gk2<=n){
plist.set(n,plist.get(n)+flag*plist.get(n-gk2));
}
plist.set(n,plist.get(n)%limit);
flag*=-1;
}
if(plist.get(n)==0)
break;
n++;
}
System.out.println(n);
}
// 55374
// running time=0s784ms
void partitions1(int limit){
ArrayList<Integer> plist = new ArrayList<Integer>();
plist.add(1);
int n = 1;
int flag;
while(true){
int gk = 1;
int i = 0;
plist.add(0);
while(gk<=n){
flag = (i%4>1)?-1:1;
plist.set(n,plist.get(n)+flag*plist.get(n-gk));
plist.set(n,plist.get(n)%limit);
i++;
int k= (i%2==0)?i/2+1:-(i/2+1);
gk = k*(3*k-1)/2;
} if(plist.get(n)==0)
break;
n++;
}
System.out.println(n);
}
// 55374
// running time=1s155ms public static void main(String[] args){
long t0 = System.currentTimeMillis();
new PE078().run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms"); }
}
法三:
又给出了求k的一种方式
关键程序:
while True:
gk = k * (3 * k - 1) // 2
i = n - gk
if i < 0:
break
pt += (-1) ** (k * k + 1) * p[i]
k = -1 * k if k > 0 else 1 - k
p.append(pt)
python程序:
import time ; def partitions(limit):
p = [1, 1, 2]
n = 2
while True:
n += 1
pt = 0
i = 0
k = 1
while True:
gk = k * (3 * k - 1) // 2
i = n - gk
if i < 0:
break
pt += (-1) ** (k * k + 1) * p[i]
k = -1 * k if k > 0 else 1 - k
p.append(pt)
if pt % limit == 0:
print "n =", n, "\n"+"partition =", pt
break if __name__=='__main__':
t0 = time.time()
limit = 1000000
partitions(limit)
t1 = time.time()
print "running time=",(t1-t0),"s" # n = 55374
# running time= 21.3049998283 s
说明:只有第一种方法是我自己写的,其他是在论坛看到的,自己整理的
Project Euler 78:Coin partitions的更多相关文章
- Python练习题 039:Project Euler 011:网格中4个数字的最大乘积
本题来自 Project Euler 第11题:https://projecteuler.net/problem=11 # Project Euler: Problem 10: Largest pro ...
- [project euler] program 4
上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...
- Python练习题 029:Project Euler 001:3和5的倍数
开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...
- Project Euler 9
题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...
- Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.
In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...
- project euler 169
project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...
- 【Project Euler 8】Largest product in a series
题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...
- Project Euler 第一题效率分析
Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...
- Python练习题 049:Project Euler 022:姓名分值
本题来自 Project Euler 第22题:https://projecteuler.net/problem=22 ''' Project Euler: Problem 22: Names sco ...
随机推荐
- 将json转为复杂url参数
//json转url参数 var parseParam = function(param, key) { var paramStr = ""; if (param instance ...
- linux服务器修改ftp默认21端口方法
1.登录服务器,打开vsftp.conf文件 # vim /etc/vsftpd/vsftpd.conf 2.在文件末尾增加listen_port=8021 #remote_charset=CP125 ...
- Linux之父访谈录:设计内核只为了好玩
2010-09-20 10:36 “有 些人生来就具有统率百万人的领袖风范;另一些人则是为写出颠覆世界的软件而生.唯一一个能同时做到这两 者的人,就是Linus Torvalds.”这是美国<时 ...
- openerp学习笔记 计算字段支持搜索
示例1: # -*- encoding: utf-8 -*-import poolerimport loggingimport netsvcimport toolslogger = netsvc.Lo ...
- asp.net 生成PDF方法
今天转博客园看到有人发表了一篇生成PFd的文章,准备自己也留一份准备以后用到的时候方便调用: 首先去itextsharp网站下载控件(https://sourceforge.net/projects/ ...
- js IDE WebStorm 注册码
webStorm : UserName:William ===== LICENSE BEGIN ===== 45550-12042010 00001SzFN0n1bPII7FnAxnt0DDOPJA ...
- AnyChartStock去除水印方法
最近在使用AnyChartStock的图表,功能很强大,但下载过来是有水印的,虽然网上也有很多破解无水印的版本,但基本都是AnyChart的,AnyChartStoc的几乎没有.所以自己尝试着去除水印 ...
- C# 实现Oracle中的数据与Excel之间的转换
最近项目要求实现数据库之间数据在各个数据库之间导入导出,在此做个笔记 1. 将Oracle中的表导入到Excel中,反之亦然 private static readonly string conne ...
- 【个人笔记】001-PHP基础-01-PHP快速入门-01-PHP职业路线及PHP前景
001-PHP基础-01-PHP快速入门 01-PHP职业路线及PHP前景 PHP职业路线 PHP初级工程师 1年以下 3k-6k PHP中级工程师 1-3年6k-10k PHP高级工程师 3年以上 ...
- redhat或centos关闭防火墙并开启sshd服务
使用putty连接虚拟机的redhat连不上时处理方案: 这里使用的是VMware Workstation, 将宿主机与虚拟机之间的网络使用 ‘桥接方式’: 1.关闭宿主机与虚拟机的防火墙, 在re ...