1632 Sumsets【转】
来源:互联网 发布:vb循环语句do while 编辑:程序博客网 时间:2024/05/17 04:32
Sumsets
总提交: 0 测试通过: 0
描述
Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7:
1) 1+1+1+1+1+1+1
2) 1+1+1+1+1+2
3) 1+1+1+2+2
4) 1+1+1+4
5) 1+2+2+2
6) 1+2+4
Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000).
输入
输出
样例输入
7
样例输出
6
原创总结:看起来像母函数,如果大数据超时夸张,可以考虑找规律。
分析:
转自:http://hi.baidu.com/mad4alcohol/blog/item/744edc9472ac3c41d0135e1c.html
以s[i]表示i的拆分方案总数,则
如果i为奇数,那么s[i] = s[i - 1],否则s[i] = s[i / 2] + s[i - 1]
为什么?想想以下的例子,你就明白了:
7 =
1 + 1 + 1 + 1 + 1 + 1 + 1 =
1 + 1 + 1 + 1 + 1 + 2 =
1 + 1 + 1 + 2 + 2 =
1 + 1 + 1 + 4 =
1 + 2 + 2 + 2 =
1 + 2 + 4
6 =
1 + 1 + 1 + 1 + 1 + 1 =
1 + 1 + 1 + 1 + 2 =
1 + 1 + 2 + 2 =
1 + 1 + 4 =
2 + 2 + 2 =
2 + 4 =
5 =
1 + 1 + 1 + 1 + 1 =
1 + 1 + 1 + 2 =
1 + 2 + 2 =
1 + 4
4 =
1 + 1 + 1 + 1 =
1 + 1 + 2 =
2 + 2 =
4
3 =
1 + 1 + 1 =
1 + 2
2 =
1 + 1 =
2
1 =
1
可以发现:由于奇数是由一个偶数加1得到的,而这个1对方案总数没有影响,所以奇数的方案总数为它的前一个数的方案总数(即偶数的方案总数);
对于偶数x,上面说了,如果某个数由另一个数加1得到,那么这个1对方案总数没有影响,所以x的方案总数肯定有x - 1的方案总数的份,这样方案中至少包含1 + 的种类考虑到了,如果这个数的拆分方案中不包含1 + 的话(肯定是有的,因为是偶数),比如6,将它的含1 + 的方案剃掉,我们就有
6 =
2 + 2 + 2 =
2 + 4
除以2的话,我们得到了
3 =
1 + 1 + 1 =
1 + 2
这不就是3的方案吗,所以x的方案总数的第二部分就是x/2的方案总数。
综上 s[i] = s[i - 1], i is odd;
s[i] = s[i - 1] + s[i / 2], i is even.
另一个想法:
转自:http://hi.baidu.com/rain_bow_joy/blog/item/11f51c1d7e7a7a8287d6b6cd.html
最后思路是一样的找规律。
题意:
就是给定一个n,来计算有2的次方数所能组成N的种数;(ps:就喜欢看这种,简单明了的题。。
算法:(dp 可做,肯定超时啊;找规律);
一看就是个多重背包问题;最优子结构得状态方程:
再增加一个2的次方数X时,dp【i】=sum{dp[k]},k是能通过加上X的倍数等于i;
于是乎,写之;正确是正确,只是这样严重超时啊。。不是一般的超时啊。。
于是把前几十个数的结果打印出来观察;有规律。。
奇数时dp【i】=dp[i-1];
偶数时dp[i]=dp[i-2]+dp[i/2];
只是不知为甚?。。后来看到disscuss,才发现自己的弱智。。(ps:自我鄙视一小下);
当i为奇数时,可以有1加到,就是dp【i】=dp[i-1];
当i为偶数时,可以有1+1,和全部是偶数得到,就是dp[i]=dp[i-2]+dp[i/2];
另外,取后几位的话,取模一下就okay了。。
方丈的代码:
#include<iostream>
using namespace std;
long dp[1100000];
int main()
{
int N;scanf("%d",&N);
int d;
dp[1]=1;dp[2]=2;dp[3]=2;dp[4]=4;dp[5]=4;dp[6]=6;
for(d=7;d<=N;d++)
{
if(d%2) {dp[d]=dp[d-1];}
else
{
dp[d]=dp[d-2]+dp[d/2];
if(dp[d]>999999999) dp[d]%=1000000000;
}
}
printf("%d/n",dp[N]);
return 0;}
- 1632 Sumsets【转】
- Sumsets
- Sumsets
- Sumsets
- Sumsets
- Sumsets
- Sumsets
- 10125 - Sumsets(*****)
- 10125 - Sumsets
- uva10125 - Sumsets
- uva10125 Sumsets
- HDU2709 Sumsets
- 10125 - Sumsets
- POJ_2229 Sumsets
- poj2229 Sumsets
- poj2229 Sumsets
- POJ2229 Sumsets
- POJ2229 Sumsets
- pku3639 Exchange Rates (动态规划)
- php中$_SERVER参数HTTP_X_FORWARDED_FOR & REMOTE_ADDR与获取IP
- November, 09
- 注册商品
- 下面继续Flex开发
- 1632 Sumsets【转】
- [双语阅读]婴儿哭声藏玄机 声调不同因在母语
- 求书
- [双语阅读]“欧洲百万”开奖 英两幸运儿平分1亿大奖
- 转帖
- 第10章 内部类
- 基于LRU算法的Java对象池设计
- 焦点效应 spotlight effect
- 操纵比赛 game-rigging