题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=2709

题意

给出一个数N 要求有多少种方式 求和 能够等于N

加的数 必须是 2的幂次

思路

首先可以想到的是

如果 N 是奇数的话

那么 到达N 的方法数 就是 到达 N - 1 的方法数

因为就相当于 把 所有到达N-1 的方法数 都再 + 1

如果 N 是偶数的话

就有两种情况

0.分解的数字中至少有两个1 那么 dp[n] = 1 + 1 + dp[n - 2]

1.分解的数字中没有1 也就是说 是由dp[n - 2] 中每个分解方式中的数字 都*2 就是 n

所以 dp[n] = dp[n - 2] + dp[n / 2]

AC代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<list>
#include<stack>
#include <queue> #define CLR(a, b) memset(a, (b), sizeof(a)) using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 5;
const int MOD = 1e9; ll dp[maxn]; void init()
{
dp[0] = 1;
for(int i=1;i<maxn;++i)
{
if(i&1) dp[i]=dp[i-1];
else dp[i]=(dp[i-2]+dp[i/2]) % MOD;
}
} int main()
{
init();
int n;
while (~scanf("%d", &n))
{
printf("%lld\n",dp[n]%MOD);
} }

思路二

可以枚举式子中 最大的那位 是多少

比如 最大的那位是 1

dp[1] = 1;

那么

dp[n] = dp[n - 1]

此时表示的状态是 每个到N的方式 组成的数字中 只有1

最大位是2

那么

dp[n] += dp[n - 2]

因为我们是按照 最大数 枚举上去的

而不是 按照 之前的状态转移的

比如 最大数是2

那么 dp[n] 就要加上 dp[n - 2] dp[n - 2] 表示 最大数是2 来到达n - 2 的方式总数

而不是 到达 n - 2 的所有方式

AC代码

#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits> #define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair<string, int> psi;
typedef pair<string, string> pss; const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8; const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 5;
const int MOD = 1e9; int binary[25]; int dp[maxn]; void init()
{
CLR(binary, 0);
CLR(dp, 0);
binary[0] = 1;
dp[0] = 1;
for (int i = 1; i < 25; i++)
binary[i] = binary[i - 1] * 2;
for (int i = 0; i < 25 && binary[i] < maxn; i++)
{
for (int j = binary[i]; j < maxn; j++)
{
dp[j] += dp[j - binary[i]];
dp[j] %= MOD;
}
}
} int main()
{
init();
int n;
while (~scanf("%d", &n))
cout << dp[n] % MOD << endl;
}

最新文章

  1. 【WP开发】不同客户端之间传输加密数据
  2. Android Studio 如何切换sdk
  3. knockout-validation不自动插入错误消息
  4. 要让div中的float不会自动显示到下一行来?
  5. mysql 总结二(自定义存储过程)
  6. Flex 学习笔记 ComboBox内容框宽度
  7. 七牛CEO许式伟:移动游戏资源存贮的大趋势
  8. C# winForm 窗体闪烁问题
  9. SQL查询集合合并成字符串
  10. access violation at address General protection fault
  11. Linux怎么使用添加的新硬盘
  12. STM32硬件调试详解
  13. Mysql导出导入乱码问题解决
  14. Office在线预览及PDF在线预览的实现方式史上最全大集合
  15. 写个自动下载安装Ant的shell脚本【二】
  16. Java高精度学习第三弹——ACM中使用JAVA的详细介绍
  17. Hot-Bar 軟板設計注意事項
  18. Java进阶(十四)实现每天定时对数据库的操作
  19. access denied for user &#39;root&#39;@&#39;localhost&#39;(using password:YES) FOR WINDOWS
  20. quartz集群分布式(并发)部署解决方案

热门文章

  1. 仿IOS中下拉刷新的“雨滴”效果
  2. asp.net core mvc视频A:笔记3-6.视图数据共享之session/cache
  3. Security Testing Basics
  4. elk升级文档
  5. awk.sed.grep三剑客详解
  6. UVA 11354 - Bond (最小生成树 + 树链剖分)
  7. html中keydown事件
  8. ssh不检查server变化
  9. Java多线程中的竞争条件、锁以及同步的概念
  10. 值类型,Nullable类型