51nod 1383 整数分解为2的幂
这题非常厉害,建议认真看下去虽然我讲的也不好。
首先肯定先想到的是多重背包,可以把每个次幂当作物品,然后套板子。
但是这题有 \(O(n)\) 复杂度的做法,我们想如果一个数 \(i\) 是奇数,那他只能由 \((i-1)+1\) 转化过来(2的幂次只有1是奇数),那方案数就是 \(i-1\) 的方案数。如果是偶数,首先他也可以由上一个数 \(+1\) 转移过来,但他还可以由 \(i/2\) 构成的每个数 \(\times 2\) 转移过来。
对了还可以打表找规律,这是找规律的网站
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+10;
const int mod=1e9+7;
int n;
int dp[N];
int main(){
ios::sync_with_stdio(false);
cin>>n;
dp[0]=1;
dp[1]=1;
for(int i=1;i<=n;i++){
dp[i]=dp[i-1];
if(!(i&1)){//偶数
dp[i]=(dp[i]+dp[i>>1])%mod;
}
}
cout<<dp[n];
return 0;
}