递推关系找到的话,这题就没什么难度了,刚开始我使用的是基于完全背包的改造,结果超时严重,后来搜到了这篇文章,才发现原来区分奇偶性就可以了。。。
唉!分析问题的能力还是太水,继续努力吧~~
附上我的超时的代码
#include <stdio.h>
#define N 1000100
#define MOD 1000000000
int dp[N];
int main() {
int i, n;
int k, v;
while(scanf("%d", &n) != EOF) {
k = 1;
while((1<<k) < n) k++;
for(i = 0; i <= N; i++)
dp[i] = 1;
for(i = 1; i <= k; i++)
for(v = 1<<i; v <= n; v++) {
dp[v] = dp[v] + dp[v-(1<<i)];
if(dp[v] > MOD) dp[v] %= MOD;
}
printf("%d\n", dp[n]);
}
return 0;
}
接下来是AC的使用递推公式的代码
#include <stdio.h>
#define N 1000001
#define MOD 1000000000
int dp[N];
int main() {
int i, n;
while(scanf("%d", &n) != EOF) {
dp[1] = 1;
dp[2] = 2;
for(i = 3; i <= n; i++) {
if((i & 1) == 0)
dp[i] = dp[i-1] + dp[i>>1];
else
dp[i] = dp[i-1];
if(dp[i] > MOD)
dp[i] -= MOD;
}
printf("%d\n", dp[n]);
}
return 0;
}
值得一提的是,在久度上提交次版本的代码执行时间在120MS左右,最好的程序大约是20MS,我实在不知道怎么优化了,哪位读者有好的建议,麻烦在下面留言,十分感谢!