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 ...
随机推荐
- OpenSUSE 安装并启动Tomcat
安装.用YsST2搜索tomcat安装就好了.不过版本肯定不如官网的新,笔者用的是7.0.42,最新的已经到8.X了. 启动.在服务管理器中找到tomcat,启动.
- WIN2003跳出res://C:WINDOWSsystem32mys.dll/mys.hta解决方法
出现这个问题的时候 @echo off 请将以下语句复制到记事本中,另存为后缀为.cmd的文件,并运行.当然在命令行下一句句运行也没问题. echo 正在修复,这个过程可能需要几分钟,请稍候…… ru ...
- .Net 将一个DataTable分解成多个DataTable
这两天遇到一个问题,我们所接触 的一个系统在导出数据到Excel的时候,产生了内存溢出的错误.原因在于数据过大,它导出是将所有数据存放在一个DataSet的一个表中,再将这个数 据集放入session ...
- Docs list
http://www.deansys.com/doc/ldd3/index.html Github中文文档: http://www.worldhello.net/gotgithub/03-projec ...
- 《零成本实现Web自动化测试--基于Selenium》第一章 自动化测试基础
第一篇 Selenium 和WebDriver工具篇 第一章 自动化测试基础 1.1 初识自动化测试 自动化测试有两种常见方式 1.1.1 代码驱动测试,又叫测试驱动开发(TDD) 1.1.2 ...
- 关于C语言指针中的p++与p+i
先看一组代码: #include <stdio.h> void main() { int i,*p,a[7]; p=a; for(i=0;i<7;i++) scanf("% ...
- JMS概述
[1.面向消息的中间件]顾名思义,面向消息的中间件就是通过使用消息(而不是命令)将企业内的组件连接起来的系统.例如库存系统可能会与工资和会计系统进行通信,如果使用面向消息的中间件将他们连接在一起,就可 ...
- MySQL 多实例数据库还原脚本-备份集与端口对应
版本:5.5.14 OS: ConetOS 6.3 1.创建recover.sh [root@yoon export]# vi recover.sh #!/bin/bash bakdir=/exp ...
- python之量的概念
程序设计语言: 量的类型: 1. 直接量 2. 常量 3. 变量 量的因素: 1. 存储类别 2. 数据类型 3. 作用域 4. 生存期
- 日志文件切割服务logrotate配置及crontab定时任务的使用
1.下载logrotate 在Fedora和CentOS安装 yum install logrotate crontabs Debian和Ubuntu上 apt-get install logrota ...