POJ 2229 Sumsets(递推,找规律)
2015-10-17 11:52
281 查看
构造,递推,因为划分是合并的逆过程,考虑怎么合并。
先把N展开成全部为N个1
然后合并,因为和顺序无关,所以只和出现次数有关
情况有点多并且为了避免重复,分类,C[i]表示序列中最大的数为2^i时的方案数
树形表示合并 (UVA 10562 Undraw the Trees的表示方法。。。
7 (2^0) (7表示2^0出现的次数)
_ _ _
| | |
1 2 3 (2^1) (7个1可以合并成1~3个2)
_ _
| |
1 1 (2^2) (继续合并)
这棵树是分形的,子树的形态由根结点的值决定。
f
表示方案
当n是偶数,第一层会增加一颗子树 其值为 n/2, f
= f[n-1]+f[n/2]
当n是奇数,树的形态不变 ,f
= f[n-1]
先把N展开成全部为N个1
然后合并,因为和顺序无关,所以只和出现次数有关
情况有点多并且为了避免重复,分类,C[i]表示序列中最大的数为2^i时的方案数
树形表示合并 (UVA 10562 Undraw the Trees的表示方法。。。
7 (2^0) (7表示2^0出现的次数)
_ _ _
| | |
1 2 3 (2^1) (7个1可以合并成1~3个2)
_ _
| |
1 1 (2^2) (继续合并)
这棵树是分形的,子树的形态由根结点的值决定。
f
表示方案
当n是偶数,第一层会增加一颗子树 其值为 n/2, f
= f[n-1]+f[n/2]
当n是奇数,树的形态不变 ,f
= f[n-1]
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> using namespace std; const int mod = 1e9, maxn = 1e6+1; int dp[maxn]; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif int n; cin>>n; dp[1] = 1; for(int i = 2; i <= n ; i++) { dp[i] = dp[i-1] + (i&1?0:dp[i>>1]); if(dp[i]>=mod) dp[i] -= mod; } cout<<dp <<endl; return 0; }
相关文章推荐
- Unity性能优化——LOD技术
- linux下gcc/g++编译用法
- Less中的颜色计算溢出
- GridView简单封装收缩和展开
- DEVC中的for编译出错问题解决办法
- Linux:获取当前进程的执行文件的绝对路径
- 黑马程序员--Protocol 代理协议
- 纪录、分析、反思、进步!
- MVC4.0 解决Controllers与Areas中控制器不能同名问题
- 新的开始+Grad第一学期短期规划
- Leetcode: Single Number III
- Gradle之安装Gradle
- 嵌入式linux截图工具gsnap。。。。
- 翻译:深入 AngularUI Router
- 类与对象课后作业
- OC中NSLog函数输出格式详解
- 字符集
- 浅析mongodb主从库的配置
- POJ-2105
- json中头疼的null