题目链接

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;
}

HDU - 2709 Sumsets 【递推】的更多相关文章

  1. hdu2709 Sumsets 递推

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2709 感觉很经典的一道递推题 自己想了有半天的时间了....比较弱.... 思路: 设f[n]表示和为 ...

  2. HDU 4747 Mex 递推/线段树

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=4747 Mex Time Limit: 15000/5000 MS (Java/Others)Memory Limi ...

  3. 致初学者(四):HDU 2044~2050 递推专项习题解

    所谓递推,是指从已知的初始条件出发,依据某种递推关系,逐次推出所要求的各中间结果及最后结果.其中初始条件或是问题本身已经给定,或是通过对问题的分析与化简后确定.关于递推的知识可以参阅本博客中随笔“递推 ...

  4. poj2229 Sumsets (递推)

    http://poj.org/problem?id=2229 看到题目能感觉到多半是动态规划,但是没有清晰的思路. 打表找规律: #include<cstdio> #include< ...

  5. HDU 2604 Queuing(递推+矩阵)

    Queuing [题目链接]Queuing [题目类型]递推+矩阵 &题解: 这题想是早就想出来了,就坑在初始化那块,只把要用的初始化了没有把其他的赋值为0,调了3,4个小时 = = 本题是可 ...

  6. HDU - 2604 Queuing(递推式+矩阵快速幂)

    Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. hdu 1723 DP/递推

    题意:有一队人(人数 ≥ 1),开头一个人要将消息传到末尾一个人那里,规定每次最多可以向后传n个人,问共有多少种传达方式. 这道题我刚拿到手没有想过 DP ,我觉得这样传消息其实很像 Fibonacc ...

  8. hdu 1249 三角形 (递推)

    三角形 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  9. [hdu 2604] Queuing 递推 矩阵快速幂

    Problem Description Queues and Priority Queues are data structures which are known to most computer ...

  10. HDU 5366 dp 递推

    The mook jong Accepts: 506 Submissions: 1281 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...

随机推荐

  1. py定义变量-循环-条件判断

    定义变量 # print('hahaha')name = " let'go "title = '刘伟长得 "很帅"!'conent = '''     let' ...

  2. java如何实现多个线程并发运行

    随着计算机技术的发展,编程模型也越来越复杂多样化.但多线程编程模型是目前计算机系统架构的最终模型.随着CPU主频的不断攀升,X86架构的硬件已经成为瓶,在这种架构的CPU主频最高为4G.事实上目前3. ...

  3. Excel中判断一个表中的某一列的数据在另一列中是否存在

      A B C D 1 10   3 有 2 6   e 无 3 3   6 有 判断c列的值在A列中是否存在(假定C列为需要判断列,A列为目标列) 在D1中输入以下公式,然后下拉公式即可 =IF(C ...

  4. 数据结构之shell排序

    #SIZE  10        //直接插入排序     void insert_sort(){           int i,j;           int array[SIZE+1];   ...

  5. ros之串口通信---imu

    1.sudo apt-get install ros-kinetic-rosserial 或者sudo git clonegit://github.com/wjwwood/serial.git  (开 ...

  6. PHP高级工程师的要求

    PHP 高级工程师1名,(3年以上工作经验  )   1.熟悉unix环境编程,如多线程/多进程,IO复用.锁.定时器.新号.信号量.共享内存.消息队列.文件系统2.熟悉php的stream.sock ...

  7. lua学习笔记(四)

      表达式   算术操作符     +(加法) -(减法) *(乘法) /(除法) ^(指数) %(取模) -(负号)     x%1的结果是x的小数部分,x-x%1是整数部分   关系操作符     ...

  8. log4j日志异步化大幅提升系统性能

    .log4j已成为大型系统必不可少的一部分,log4j可以很方便的帮助我们在程序的任何位置输出所要打印的信息,便于我们对系统在调试阶段和正式运行阶段对问题分析和定位.由于日志级别的不同,对系统的性能影 ...

  9. PHPstudy如何在本地搭建多站点

    参考地址: http://jingyan.baidu.com/article/e52e36154227ef40c70c5147.html

  10. [学英语]vocabulary.com你都可以怎么用

    vocabulary.com你都可以怎么用? 核心就是背单词. 1.利用纯英文环境熟悉单词,看看他们是如何解释单词的. 2.对于大段的文章,可以提炼出你需要背的单词. 3.以游戏的方式来背单词,app ...