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的更多相关文章

  1. Python练习题 039:Project Euler 011:网格中4个数字的最大乘积

    本题来自 Project Euler 第11题:https://projecteuler.net/problem=11 # Project Euler: Problem 10: Largest pro ...

  2. [project euler] program 4

    上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...

  3. Python练习题 029:Project Euler 001:3和5的倍数

    开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...

  4. Project Euler 9

    题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...

  5. 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 ...

  6. project euler 169

    project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...

  7. 【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 × ...

  8. Project Euler 第一题效率分析

    Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...

  9. Python练习题 049:Project Euler 022:姓名分值

    本题来自 Project Euler 第22题:https://projecteuler.net/problem=22 ''' Project Euler: Problem 22: Names sco ...

随机推荐

  1. [大牛翻译系列]Hadoop(12)MapReduce 性能调优:诊断硬件性能瓶颈

    6.2.5 硬件性能问题 尽管单独的硬件的MTTF(平均失效前时间)都数以年记,然而在集群中就完全不是这么一回事了.整个集群的MTTF就要小得多.这一节要介绍如何确定CPU,内存,磁盘和网络是否过度利 ...

  2. jQuery之$(document).ready()使用介绍

    学习jQuery的第一件事是:如果你想要一个事件运行在你的页面上,你必须在$(document).ready()里调用这个事件 学习jQuery的第一件事是:如果你想要一个事件运行在你的页面上,你必须 ...

  3. SQL 查询分析器操作(修改、添加、删除)表及字段等

    一.库操作1..创建数据库命令:create database <数据库名>例如:建立一个名为xhkdb的数据库mysql> create database xhkdb; 2.显示所 ...

  4. Windows 注册表 (未完成)

    由于最近需要用到注册表,并且操作很多系统设置,所以想吧关于微软注册表的东西都写出来,找了很久才发现,微软对于注册表做了很详细的说明,但是为了节省时间翻译文本为自动翻译,手动纠错,欢迎大家指出错误. 根 ...

  5. vs2010中安装ASP.NET AJAX Control Toolkit

    方法一: 第一步 下载Ajax Control Toolkit 进入网址http://ajaxcontroltoolkit.codeplex.com/ 即可下载 第二步 解压下载下来的Ajax Con ...

  6. perl中shift 和unshift 操作

    ##################################################################### unshift 和shift 对一个数组的开头进行操作(数组 ...

  7. java调用存储过程和函数

    以对表test进行增,删,改,查进行说明:1.新建表test create table TEST ( TID NUMBER not null, TNAME VARCHAR2(32), TCODE VA ...

  8. Linux nmon 监控工具使用

    Linux 系统下监控指标及指标查看 一.工具介绍     Linux 系统下资源监控使用nmon 工具.它可以帮助在一个屏幕上显示所有重要的性能优化信息,并动态地对其进行更新且并不会消耗大量的CPU ...

  9. 关于C与C++的struct,union,enum用法差异

    对着代码说话: #include <stdio.h> #include <stdlib.h> struct test { int abc; }; enum _enum {A,B ...

  10. centos Supervisor

    Supervisor是一个进程监控程序. 满足的需求是:我现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,我就需要使用到了 ...