博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Project Euler 78:Coin partitions
阅读量:5944 次
发布时间:2019-06-19

本文共 4437 字,大约阅读时间需要 14 分钟。

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值。

 

思路:

求数的拆分有多少种

再判断是否能被一百万整除

 

参考资料: ,

 

法一:

 

根据这个等式:

高能预警:

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
plist = new ArrayList
(); 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
plist = new ArrayList
(); 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

 

说明:只有第一种方法是我自己写的,其他是在论坛看到的,自己整理的

转载地址:http://tuwxx.baihongyu.com/

你可能感兴趣的文章
layer弹出信息框API
查看>>
delete from inner join
查看>>
WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍...
查看>>
git merge 和 git merge --no-ff
查看>>
独立软件开发商进军SaaS注意八个问题,互联网营销
查看>>
jdk内存的分配
查看>>
关于self.用法的一些总结
查看>>
UIView翻译 (参考)
查看>>
Android Display buffer_handle_t的定义
查看>>
SSH详解
查看>>
ASM概述
查看>>
【290】Python 函数
查看>>
godaddy域名转发(域名跳转)设置教程
查看>>
silverlight学习布局之:布局stackpanel
查看>>
理解并自定义HttpHandler
查看>>
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
JavaScript标准库系列——RegExp对象(三)
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
关于缓存命中率的几个关键问题!
查看>>
oracle中create table with as和insert into with as语句
查看>>