Time Limit: 2000MS | Memory Limit: 200000K | |
Total Submissions: 22646 | Accepted: 8681 |
Description
1) 1+1+1+1+1+1+1
2) 1+1+1+1+1+2
3) 1+1+1+2+2
4) 1+1+1+4
5) 1+2+2+2
6) 1+2+4
Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000).
Input
Output
Sample Input
7
题目大意:让你求一个整型N,能够被2的整数幂所组成的情况个数,最终的结果要mod1e9;
先说说我的思路,由于刚看完dp之划分数,本以为是划分数,结果看完大牛的题解后发现是完全背包,但是我感觉用递推来做更好想(哪个都不好想光是递推就看了很长时间),下面讲一下思路:
当n时奇数时,dp[n]=dp[n-1],拿样例7来说,无非就是在6的每种情况下+1呗(这比是偶数的情况好想到,也好理解,至少我认为是这样的),奇数肯定每一种组合数中都会有1的,从下面来看dp[6]的每一种组合情况+1的结果是不变的。
1) 1+1+1+1+1+1 +1;
2) 1+1+1+1+2 +1 ;
3) 1+1+2+2 +1;4) 1+1+4 +1;
5) 2+2+2 +1;
6) 2+4 +1;
即dp[i]=dp[i-1]
当n是偶数的情况 我拿n=6来说,以下是6的组合情况:
111111 11112 1122 114 222 24
共有6种,我们可以把它分为有1的情况和没有1的情况 把有1 的情况拿出减去分别-1 得到11111 1112 122 14这是dp[5]的结果 ,接下来看剩下没有1 的组合数222 和24将它们都除以2得到111 12两种情况(这是dp[2]的情况),无非就是dp[2]每一项*2的结果,并且结果不变
即dp[i]=dp[i-1]+dp[i/2];
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXN 40005
#define mem(a,b) memset(a,b,sizeof(a));//算是宏定义的应用吧
int dp[1000004];
int N=1e9;
int main()
{
mem(dp,0);
int n;
cin>>n;
dp[1]=1;
for(int i=2;i<=n;i++)
{
if(i&1==1)//利用位运算,奇数的二机制的最后一位都是1
dp[i]=dp[i-1];
else
dp[i]=(dp[i-1]+dp[i>>1])%N;//dp[i>>1]是/2的意思,反之i<<1左移1位是*2;
}
cout<<dp[n]<<endl;
return 0;
}