传送门

题意

  将一个数N分解为2的幂之和共有几种分法?

题解

  定义dp[ i ]为 i 的分解方案数。

  初始化dp[0] = 2= 1;

  状态转移方程为:

  for i : 1 to N

    若 i 为偶数,则dp[ i ] = dp[ i / 2] + dp[i – 1] ;

    否则dp[i] = dp[ i – 1];

对状态转移方程的理解:

  打个表先~~~~

  i  i 的分解方案

  1......1

  2......1+1,2

  3......1+1+1,2+1

  4......(2+1+1),(1+1+1+1),(2+2),(4)

  5......2+1+1+1,1+1+1+1+1,2+2+1,4+1

  6......2+1+1+1+1,1+1+1+1+1+1,2+2+1+1,4+1+1,2+2+2,4+2

  7......(2+1+1+1+1+1),(1+1+1+1+1+1+1),(2+2+1+1+1),(4+1+1+1),(2+2+2),(4+2+1)

  8......(2+1+1+1+1+1+1),(1+1+1+1+1+1+1+1),(2+2+1+1+1+1),(4+1+1+1+1),(2+2+2),(4+2+1+1),(4+2+2),(2+2+2+2),(4+4),(8)

  以8的为例,dp[8]=dp[20+7]+dp[2* 4];

  8分解成2的幂之和,只能分解成2, 2, 2, 23之间的加和。

  如果分解方案中含有20,并且不能出现重复,那可以考虑7的分解方案中的每个方案都+1 <=> 8的含20的分解方案总数(对应表中橘色部分);

  因为dp[7]中的分解方案数是不重复的,所以每个方案数+1也是不重复的;

  那,如何使分解方案中不含有20呢?

  想一下4的分解方案数是怎么得到的?

  4分解成2的幂之,只能分解成2, 2, 22之间的加和;

  如果4中的每个方案都 ×2,那不就正好变成8的分解方案中只不含有20的分解方案了吗(对应表中蓝色部分)?

  如果 i 为奇数,就不能通过某数 ×2 来得到 i;

  那也就是说只能通过 (i-1) 方案中每个方案+1 得到 i 的所有分解方案,故dp[ i ]=dp[ i-1]

•Code

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. const int MOD=1e9;
  5. const int maxn=1e6+;
  6.  
  7. int N;
  8. int dp[maxn];
  9.  
  10. int main()
  11. {
  12. scanf("%d",&N);
  13. dp[] = ; // 2^0
  14. for(int i=;i <= N;++i)
  15. {
  16. if ((i & 0x1) == )//判断i是否为偶数
  17. dp[i]=dp[ i / ]; //将i/2的每个构成数乘以2,得到 i
  18. dp[i] += dp[i - ]; //将i-1的构成数拿过来加一
  19. dp[i] %= MOD;
  20. }
  21. printf("%d\n",dp[N]);
  22. return ;
  23. }

分割线:2019.6.16

•类比“n的m划分”

重新理解了一下“n的m划分”这种题的求解方法,想到了这道题;

感觉这道题和n的m划分很像;

n的m划分在状态转移时考虑的是“划分数种是否包含0这个元素”;

而在此题中,考虑的是“是否包含20这个元素”;

这应该是有两者的性质决定的,前者需要的是任意数的累加,后者需要的是2的幂的累加;

而任意数中的最小值为0,2的幂的最小值为20=1;

根据最小值的不同,考虑的不包含的数也不同;

此题中,数 i 的划分可分为两类:

①包含20

②不包含20

包含 2很好办,直接将 i-1 的划分 +1 便可得到 i 的划分中包含 20 的划分方案数;

主要是不包含20要如何求解?

与n的m划分相仿,如果 i 为偶数,那么将 i/2 中划分 ×2 得到的就是 i 的划分不包含 20 的划分方案数;

根据上述讲解定义dp[ i ]表示 i 的划分方案数;

那么 dp[ i ]=dp[ i ]-1 + ( i为偶数 ? dp[ i/2 ] : 0);

dp[ 1 ] = 1;

Code

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. #define ll long long
  5. const int maxn=1e6+;
  6. const ll MOD=1e9;
  7.  
  8. int n;
  9. ll dp[maxn];
  10.  
  11. ll Solve()
  12. {
  13. dp[]=;
  14. for(int i=;i <= n;++i)
  15. {
  16. dp[i]=dp[i-];
  17. if(!(i&))
  18. dp[i] += dp[i>>];
  19. dp[i] %= MOD;
  20. }
  21. return dp[n]%MOD;
  22. }
  23. int main()
  24. {
  25. scanf("%d",&n);
  26. printf("%lld\n",Solve());
  27. return ;
  28. }

poj 2229 Sumsets(记录结果再利用的DP)的更多相关文章

  1. NOIP 提高组 2014 飞扬的小鸟(记录结果再利用的DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9937201.html 参考资料: [1]:https://www.luogu.org/blog/xxzh242 ...

  2. poj 2385 Apple Catching(记录结果再利用的动态规划)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题意: 有两颗苹果树,在每一时刻只有其中一棵苹果树会掉苹果,而Bessie可以在很短的时 ...

  3. poj -2229 Sumsets (dp)

    http://poj.org/problem?id=2229 题意很简单就是给你一个数n,然后选2的整数幂之和去组成这个数.问你不同方案数之和是多少? n很大,所以输出后9位即可. dp[i] 表示组 ...

  4. 记录结果再利用的"动态规划"之背包问题

    参考<挑战程序设计竞赛>p51 https://www.cnblogs.com/Ymir-TaoMee/p/9419377.html 01背包问题 问题描述:有n个重量和价值分别为wi.v ...

  5. POJ 2229 Sumsets

    Sumsets Time Limit: 2000MS   Memory Limit: 200000K Total Submissions: 11892   Accepted: 4782 Descrip ...

  6. 记录结果再利用的"动态规划"

    2018-09-24 15:01:37 动态规划(DP: Dynamic Programming)是算法设计方法之一,在程序设计竞赛中经常被选作题材.在此,我们考察一些经典的DP问题,来看看DP究竟是 ...

  7. poj 2229 Sumsets(dp)

    Sumsets Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 400000/200000K (Java/Other) Total Sub ...

  8. poj 2229 Sumsets 完全背包求方案总数

    Sumsets Description Farmer John commanded his cows to search for different sets of numbers that sum ...

  9. POJ 2229 Sumsets(找规律,预处理)

    题目 参考了别人找的规律再理解 /* 8=1+1+1+1+1+1+1+1+1 1 8=1+1+1+1+1+1+1+2 2 3 8=1+1+1+1+2+2 8=1+1+1+1+4 4 5 8=1+1+2 ...

随机推荐

  1. dreamweavercs 和dreamweaver cc的區別

    https://zhidao.baidu.com/question/1541178469432885667.html

  2. nginx 负载均衡(默认算法)

    使用 nginx 的upstream模块只需要几步就可以实现一个负载均衡: 在 nginx 配置文件中添加两个server server { listen ; server_name 192.168. ...

  3. codeforces474D

    Flowers CodeForces - 474D 话说某个幸运的小伙伴X拿到了kevin女神送的蛋糕,然而他的吃法非常奇特,他独创了两种吃蛋糕的办法:一.一次吃一整个蛋糕:二.一次吃k个蛋糕. 那么 ...

  4. PKU2018校赛 H题 Safe Upper Bound

    http://poj.openjudge.cn/practice/C18H 题目 算平均数用到公式\[\bar{x}=\frac{x_1+x_2+x_3+\cdots+x_n}{n}\] 但如果用in ...

  5. Codeforces Round #483 Div. 1

    A:首先将p和q约分.容易发现相当于要求存在k满足bk mod q=0,也即b包含q的所有质因子.当然不能直接分解质因数,考虑每次给q除掉gcd(b,q),若能将q除至1则说明合法.但这个辣鸡题卡常, ...

  6. Git——取消merge状态

    MERGING状态 取消MERGING 查看更新历史 $ git reflog 恢复之前状态 $ git reset --hard 06a5578

  7. Cetos 7 系统安装备注事项

    说明:此篇内容为个人记录备注事项,具体的安装操作请参考其他教程: 系统安装: 公司的服务器型号为戴尔R330 卡片式服务器,安装过程中遇到一些问题,此文章中简单记录下 1.下载一份Cetos 系统镜像 ...

  8. 初步了解HTML

    超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言. 您可以使用 HTML 来建立自己的 WEB 站点,HTML 运行在浏览器上 ...

  9. 洛谷P1622释放囚犯

    题目: 这个题很明显是一个区间DP,但是比较不同的是,这个题它很像区间DP的经典题——石子合并. 然后我傻傻的搞了这个题搞了一下午,然后几乎看遍了全网的题解,就只看懂了这个方法,可能是我太菜了吧,但是 ...

  10. groovy的效率问题

    刚开始学groovy,知道了它会先变异成class 文件,然后再用jvm 执行.写了Hello World程序,查看它的编译文件,发现groovy的效率挺低的.不但编译文件的代码多,而且需要依赖很多g ...