projecteuler No.77 Prime summations

原文题目链接:

http://projecteuler.net/problem=77

翻译题目链接:

http://pe.spiritzhang.com/index.php/2011-05-11-09-44-54/78-77

通过人数:9126



题目分析:

用大脑估算了一下,1000的2、3、5分解的数目就在5000以上,此题答案远小于1000,内存足够,考虑使用动态规划。

构建基本状态点为n的分解成大小不超过m的质数和的数目。打算先试一下普通的递归,如果不行的话考虑优化,如果再不行的话考虑记忆化搜索或者动态规划(实际上这道题只要普通的递归就可以秒解了~所以说后面的步骤我也没有尝试。)


解题过程(代码仅供参考,因为偷懒,代码风格什么的实在不好意思...):

一、1000以内的质数打表备用:

for (int i = 2; i < 1000; i++)
{
	for (int j = 2; j * j <= i; j++)
	{
		if (i % j == 0)
			goto next;
	}
	p[l] = i;
	l++;
	next:;
}
l表示目前意境存进去的质数数目,初始为0.

这么写未必是最快的写法,也未必是最短的写法,只是比较朴素而已,毕竟只求1000以内的质数花不了多少时间,懒得用什么花招(或者确切的说:一些计算质数的经典算法)


二、递归计算m的分解成大小不超过n的质数和的数目

int count(int m, int n)
{
	if (n > m)
		return count(m, m);
	if (m == 0)
		return 1;
	if (n < 2)
		return 0;

	int t;
	for (int i = 0;; i++)
	{
		if (p[i] > n)
		{
			t=p[i - 1];
			break;
		}
	}

	int r = 0;
	while(m >= 0)
	{
		r+=count(m, t-1);
		m -= t;
	}

	return r;
}
没什么可说的~


三、计算输出结果:

int mm[1000]={0};
for (int i = 2;i<1000;i++)
{
	mm[i]=count(i,i);
	if (mm[i]>5000)
	{
		printf("%d\n",i);
		break;
	}
}
最后发现很快地就在i=71的时候突破了5000.于是就没有再做任何优化。把中间计算数值存进mm[i]中,方便debug。


分析:没有想象的难,毕竟71就到了,如果改成5000万的话或许会比较有意思...不过发现如果把5000改成50000000的话,直接递归还是可以做...数值是237(其分解成质数和的方法数为50909577)...所以说还是要改成5万亿左右吧~



以上只是我做题时的解法。

如果有更好的解法、更好的思路,欢迎评论讨论~O(∩_∩)O~



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值