POJ 2229 Sumsets(基础DP)

如果i是奇数,那么因为他只比他前一个偶数多一个1,所以他和前一个偶数的分解数目是一样的。如果i是偶数,我们不妨按照1,2,4,8...的

顺序来分解i。这样,如果第一个分解的元素为1,那么i就和i-1和分解数目相同。如果第一个分解的元素为2或2的m次方,则第二个(包括2)之后的元素均为偶数,这样各个元素除以2,于是i和i/2的分解数目相同,所以如果i是偶数,那么num[i]=num[i-1]+num[i/2]

 /*
 qq:1239198605
 ctgu_yyf
        */

#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
#define mod 1000000000
int dp[1000005];
 

int main()
{
   ios::sync_with_stdio(false);
   
   memset(dp,0,sizeof(dp));
   
   dp[0]=1; //1=2^0
   
   for(int i=1;i<1000005;i++)
   {
   	//如果i是奇数 那么它只能等于偶数的种类 因为无论如何都是往后加一个2^0 
   	if(i&1)
   	dp[i]=dp[i-1];
   	
   	else
   	dp[i]=(dp[i-1]+dp[i>>1])%mod;
   }
   
   int n; 
   while(cin>>n)
   {
   	cout<<dp[n]<<endl;
   }
   


return 0;
}

猜你喜欢

转载自blog.csdn.net/k_koris/article/details/81909308