传送门

题意

  将一个数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

 #include<iostream>
#include<cstdio>
using namespace std;
const int MOD=1e9;
const int maxn=1e6+; int N;
int dp[maxn]; int main()
{
scanf("%d",&N);
dp[] = ; // 2^0
for(int i=;i <= N;++i)
{
if ((i & 0x1) == )//判断i是否为偶数
dp[i]=dp[ i / ]; //将i/2的每个构成数乘以2,得到 i
dp[i] += dp[i - ]; //将i-1的构成数拿过来加一
dp[i] %= MOD;
}
printf("%d\n",dp[N]);
return ;
}

分割线: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

 #include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
const int maxn=1e6+;
const ll MOD=1e9; int n;
ll dp[maxn]; ll Solve()
{
dp[]=;
for(int i=;i <= n;++i)
{
dp[i]=dp[i-];
if(!(i&))
dp[i] += dp[i>>];
dp[i] %= MOD;
}
return dp[n]%MOD;
}
int main()
{
scanf("%d",&n);
printf("%lld\n",Solve());
return ;
}

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. Java调用.NET 的Web Service服务故障排除

    参考路径:http://blog.sina.com.cn/s/blog_4c925dca01014y3r.html

  2. User Authentication with Angular and ASP.NET Core

    User authentication is a fundamental part of any meaningful application. Unfortunately, implementing ...

  3. BZOJ 1443 游戏(二分图博弈)

    新知识get. 一类博弈问题,基于以下条件: 1.博弈者人数为两人,双方轮流进行决策.2.博弈状态(对应点)可分为两类(状态空间可分为两个集合),对应二分图两边(X集和Y集).任意合法的决策(对应边) ...

  4. 数据库中事务的四大特性(ACID)

    本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务 ...

  5. 关于jQuery.when()用法

    1.该方法在jQuery1.5开始被引入. 2.用法测试 a. var url1 = "/resource/ar/hometab/index_tab_games.json", ur ...

  6. Ionic生命周期与注意点

    需要注意的地方是:在走页面的生命周期以前,会先走构造方法 构造方法只走一次,除非再次创建这个页面.所以如果先push了一个新页面,然后再调用pop()返回到之前的页面,那么是不会走构造方法里面的方法的 ...

  7. 微信小程序Dom事件实现

    面对微信小程序,可能没有像我们平时使用JQuery那样随心所欲.本篇就是为了解决这个问题. 请合理使用工具! 细节就不说了,直接备份一个实现的案例: wxml <view class=" ...

  8. a span做成按钮样式不选中文字

    a,span做成按钮样式时,文字会被选中.加以下CSS可以让其不选中.测试三大浏览器都可以 .button { display: inline-block; -moz-user-select: non ...

  9. CF527E Data Center Drama(构造+欧拉回路)

    题目链接 大意: 给你一个无向图. 要求加最少的边,然后给这些无向图的边定向,使得每一个点的出入度都是偶数. 输出定向后的边数和边集. n<=10^5 m<=2*10^5 很巧妙的构造题- ...

  10. CAN总线要点

    前言 CAN总线的应用在现在看来越来越广泛,我厂设备从最初的ARM9与ARM7平台.期间升级过度到CortexA8与Cortex M3平台,再到现在的Cortex M4平台,围绕CAN进行了一系列产品 ...