【题意】将一个数用二进制数表示,求一共有多少种表示方法。
【分析】思路一:完全背包
【代码】
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <set> #include <map> #include <algorithm> #include <stack> #include <queue> #include <cmath> #include<ctime> using namespace std; const int INF=0x3fffffff,maxn=1e5+40; const int mod=1000000; const int total=2000050; int f[total]; int main (void) { int T,temp; f[0]=1; scanf("%d",&T); for(int i=0;i<=20;i++)//2^20<total<2^21 for(int j=(1<<i);j<total;j++) f[j]+=f[j-(1<<i)]%mod; while(T--) { scanf("%d",&temp); printf("%d ",f[temp]%mod); } }
代码在zoj上AC,但是在soj上就一直TLE,改了好久才勉强AC........渣哭
思路二:看了别人的博客,可以用递推思想,从二进制数的角度,任何一个数都可以由他前一个数+1表示,但如果该数n是偶数,那么他还可以由他的一半n/2表示,即将n/2左移一位
【代码】
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <set> #include <map> #include <algorithm> #include <stack> #include <queue> #include <cmath> #include<ctime> using namespace std; const int INF=0x3fffffff,maxn=1e5+40; const int mod=1000000; const int total=2000050; int f[total]; int main (void) { int T,num; f[0]=1; for(int i=0;i<total;i++) { if(i%2==0) f[i]=(f[i/2]+f[i-1])%mod; else f[i]=f[i-1]%mod; } scanf("%d",&T); while(T--) { scanf("%d",&num); printf("%d ",f[num]); } }