Project Euler 76:Counting summations
原题:
It is possible to write five as a sum in exactly six different ways:
4 + 1
3 + 2
3 + 1 + 1
2 + 2 + 1
2 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1
How many different ways can one hundred be written as a sum of at least two positive integers?
翻译:
加和计数
将5写成整数的和有6种不同的方式:
4 + 1
3 + 2
3 + 1 + 1
2 + 2 + 1
2 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1
将100写成整数的和有多少种不同的方式?
解题思路:
将100能够拆成整数的和能够有多少种?
1.利用动态规划求解
2.利用数的拆分求解<组合数学中有讲解>
数的拆分法
理论基础,链接中讲到了拆分的理论

P(n,k)的意思就是n拆分成k份的数量
有递推公式:
P(n,k)= P(n-1,k-1) + P(n-k,k)
初始值:
k>n时:P(n,k) = 0
对所有的n,P(n,n)=1,P(n,0)=0
也很显然的发现:
对所有的n,P(n,1)=n,P(n,2) = n/2 的向下取整
证明:P(n,k)= P(n-1,k-1) + P(n-k,k)
忘了。。。
求出所以的P(n,k)矩阵
则n的所以拆分的和是 
Java程序:
// 整数n 拆分k份
void partitions(){
int limit = 100;
int count = 0;
int[][] p = new int[limit+1][limit+1];
for(int n=0;n<=limit;n++){
p[n][n] = 1;
p[n][1] = 1;
p[n][0] = 0;
}
for(int n=1;n<=limit;n++){
for(int k=1;k<=n;k++){
p[n][k] = p[n-1][k-1] + p[n-k][k];
if(n==limit)
count+=p[n][k];
}
}
count = count - 1;
System.out.println(count);
}
结果:
// 190569291
// running time=0s0ms
利用递归程序:
void getPar(){
int limit = 100;
int count = 0;
for(int k=1;k<=limit;k++)
count+=Par(100,k);
count = count-1;
System.out.println(count);
}
//递归形式 整数n 拆分k分
int Par(int n,int k){
if(k==1||n==k) return 1;
if(k>n) return 0;
return Par(n-1,k-1)+Par(n-k,k);
}
结果:
// 190569291
// running time=1s869ms
递归时间明显长了许多
动态规划求解
//动态规划求解
void dp(){
int limit = 100;
int[] ways = new int[limit+1];
ways[0] = 1 ;
for(int i=1;i<=limit-1;i++){
for(int j = i;j<=limit;j++)
ways[j] += ways[j-i];
}
System.out.println(ways[limit]);
}
// 190569291
// running time=0s0ms
还看不懂
完整java程序:
package Level3;
public class PE076{ void run(){ // dp();
// partitions();
// getPar();
int res = partitions3(100,100);
res = res - 1;
System.out.println(res);
}
int partitions3(int n,int m ){
if(n<=1) return 1;
if(m>n) return partitions3(n,n);
int sum = 0;
for(int k=1;k<=m;k++)
sum+=partitions3(n-k,k);
return sum;
}
// 190569291
// running time=10s845ms
void getPar(){
int limit = 100;
int count = 0;
for(int k=1;k<=limit;k++)
count+=Par(100,k);
count = count-1;
System.out.println(count);
}
// 190569291
// running time=1s869ms
//递归形式 整数n 拆分k分
int Par(int n,int k){
if(k==1||n==k) return 1;
if(k>n) return 0;
return Par(n-1,k-1)+Par(n-k,k);
}
// 整数n 拆分k份
void partitions(){
int limit = 100;
int count = 0;
int[][] p = new int[limit+1][limit+1];
for(int n=0;n<=limit;n++){
p[n][n] = 1;
p[n][1] = 1;
p[n][0] = 0;
}
for(int n=1;n<=limit;n++){
for(int k=1;k<=n;k++){
p[n][k] = p[n-1][k-1] + p[n-k][k];
if(n==limit)
count+=p[n][k];
}
}
count = count - 1;
System.out.println(count);
// for(int n=1;n<=6;n++){
// for(int k=1;k<=n;k++)
// System.out.print(p[n][k]+" ");
// System.out.println();
// } // for(int k=0;k<=limit;k++)
// count+= p[limit][k];
// count = count - 1;
// System.out.println(count); }
// 190569291
// running time=0s0ms
//动态规划求解
void dp(){
int limit = 100;
int[] ways = new int[limit+1];
ways[0] = 1 ;
for(int i=1;i<=limit-1;i++){
for(int j = i;j<=limit;j++)
ways[j] += ways[j-i];
}
System.out.println(ways[limit]);
}
// 190569291
// running time=0s0ms public static void main(String[] args){
long t0 = System.currentTimeMillis();
new PE076().run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms"); }
}
Python实现
动态规划的效率很高
递归的已经不能忍了
import time def PE076():
res = dp();
# res = partitions(100,100)
print res
def partitions(n,m):
# limit = 100
count = 0
if n<=1 : return 1
if m>n : return partitions(n,n)
for k in range(1,m+1):
count = count + partitions(n-k,k)
return count
#
# running time=1073.04099989s
def dp():
limit = 100
ways = [0]*(limit+1)
ways[0] = 1
for n in range(1,limit):
for k in range(n,limit+1):
ways[k] +=ways[k-n]
return ways[limit]
if __name__=='__main__':
t0 = time.time()
PE076()
print "running time={0}s".format((time.time()-t0))
Project Euler 76:Counting summations的更多相关文章
- Project Euler 77:Prime summations
原题: Prime summations It is possible to write ten as the sum of primes in exactly five different ways ...
- Project Euler 85 :Counting rectangles 数长方形
Counting rectangles By counting carefully it can be seen that a rectangular grid measuring 3 by 2 co ...
- Python练习题 039:Project Euler 011:网格中4个数字的最大乘积
本题来自 Project Euler 第11题:https://projecteuler.net/problem=11 # Project Euler: Problem 10: Largest pro ...
- Python练习题 049:Project Euler 022:姓名分值
本题来自 Project Euler 第22题:https://projecteuler.net/problem=22 ''' Project Euler: Problem 22: Names sco ...
- Python练习题 048:Project Euler 021:10000以内所有亲和数之和
本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...
- Python练习题 047:Project Euler 020:阶乘结果各数字之和
本题来自 Project Euler 第20题:https://projecteuler.net/problem=20 ''' Project Euler: Problem 20: Factorial ...
- Python练习题 046:Project Euler 019:每月1日是星期天
本题来自 Project Euler 第19题:https://projecteuler.net/problem=19 ''' How many Sundays fell on the first o ...
- Python练习题 045:Project Euler 017:数字英文表达的字符数累加
本题来自 Project Euler 第17题:https://projecteuler.net/problem=17 ''' Project Euler 17: Number letter coun ...
- Python练习题 044:Project Euler 016:乘方结果各个数值之和
本题来自 Project Euler 第16题:https://projecteuler.net/problem=16 ''' Project Euler 16: Power digit sum 2* ...
随机推荐
- js----对象的创建
js创建对象的三种方法 在介绍之前一定要弄清楚一个概念,比如var a = new Object(); 这里的a并不是一个对象,而是一个对象的实例. 一.用Json创造 var a = {b:1,c: ...
- AngularJS(13)-包含
AngularJS 包含 使用 AngularJS, 你可以使用 ng-include 指令来包含 HTML 内容: 实例 <body> <div class="conta ...
- 安装gitolite,并ssh公钥无密码登录
安装gitolite,并ssh公钥无密码登录 gitolite是管理git版本库的一种方案,它将git版本库的管理信息放在了一个特殊git版本库里.gitolite与linux操作系统集成了,需要使用 ...
- [大牛翻译系列]Hadoop(11)MapReduce 性能调优:诊断一般性能瓶颈
6.2.4 任务一般性能问题 这部分将介绍那些对map和reduce任务都有影响的性能问题. 技术37 作业竞争和调度器限制 即便map任务和reduce任务都进行了调优,但整个作业仍然会因为环境原因 ...
- apache ab的安装步骤
1:到apache官方网站http://httpd.apache.org/download.cgi#apache24下载最新版本的apache,然后解压,执行如下命令: ./configure –pr ...
- 提高Linux安全性--hosts.allow, hosts.deny 文件修改方法
有一种办法来提高Linux安全性--修改 hosts.allow , hosts.deny 这2个文件来配置 允许某个ip访问, 或者禁止访问. 可以通过这种方式设置限制 sshd 的远程访问, 只允 ...
- SQL Server 数据库身份认证以及包含数据库
首先分为SQL Server 认证与Windows 身份认证. SQL Server 认证可以运行以下语句来查询 select * from sys.sql_logins 管理员可以直接修改密码,但无 ...
- 存储映射IO
mmap 将文件映射到内存, 对这块内存的修改会自动同步到相应的文件中 void *mmap(void *addr, size_t len, int prot, int flag, int fd, o ...
- 高质量的javascript代码 -- 深入理解Javascript
一. 编写高质量的javascript代码基本要点a) 可维护的代码(Writing Maintainable Code)i. 可读(注释)ii. 一致(看上去是同一个人写的)iii. 已记录b) 最 ...
- c++ 函数返回指针 及用法
#include<string> #include<iostream> using namespace std; string fun1(int a) { string str ...