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 ...
随机推荐
- 记录sublime text2的技巧
好吧,其实俺是sublime text控,用了那么的编辑器,从最初的notepad++,后来到Dreawaver,现在只钟情于sublime text2....记录一些比较实用的技巧和网站吧!! 方便 ...
- 基础学习总结(四)---内存获取、XML之PULL解析
外部项目引入如果没找到工程文件要先创建一个android项目在引入. 根据要查看的项目名在项目中搜索逐步查看 ==================== 内存详情获取: public class Mai ...
- VS2005 VS2008编译的程序在Win7下以管理员身份运行的设置
在VS2005或者VS2008 里面,直接项目右键---属性---连接器---清单文件---uac执行级别 选择requireAdministrator 重新编译 这样你的程序直接运行就拥有管理 ...
- 伴随ListView、RecyclerView、ScrollView滚动滑入滑出小图标--第三方开源--FloatingActionButton
FloatingActionButton在github上的项目主页是:https://github.com/makovkastar/FloatingActionButton 它的依赖包NineOldA ...
- uImage、zImage、bzImage、vlinzx区别
在网络中,不少服务器采用的是Linux系统.为了进一步提高服务器的性能,可能需要根 据特定的硬件及需求重新编译Linux内核.编译Linux 内核,需要根据规定的步骤进行,编译内核过程中涉及到几个重要 ...
- Linux /dev 自动创建设备节点
#include <linux/module.h> #include <linux/module.h> #include <linux/kernel.h> #inc ...
- phpstrom 7.0 序列号
phpstrom 7.0 用户名 www.goipc.cn license key 13748-1204201000001dZdtN0KxZbl8zNH8RHFCz9t"gjKv9yXf2c ...
- 【python】网络爬虫抓取图片
利用python抓取网络图片的步骤: 1.根据给定的网址获取网页源代码 2.利用正则表达式把源代码中的图片地址过滤出来 3.根据过滤出来的图片地址下载网络图片 今天我们用http://www.umei ...
- php配置步奏
web运行大致流程 浏览器输入地址,回车(发送请求) 根据规则找到对应web服务器.规则如下: 首先在本机hosts文件中找对应IP 如果hosts中没有找到,则到互联网上找对应IP 如果还 ...
- 使用libuv实现生产者和消费者模式
生产者和消费者模式(Consumer + Producer model) 用于把耗时操作(生产线程),分配给一个或者多个额外线程执行(消费线程),从而提高生产线程的响应速度(并发能力) 定义 type ...