这题当时在网络赛时很费劲的推出来的,以递推的形式写出来的,一些边界点特别不好控制,靠看数据改出来的。现在改出dfs形式,也是很简单的。
因为f(x)的数不会很大,直接保留前面枚举的数得出的结果即可。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 15000 12 #define LL long long 13 //#define INF 1e18+1e12 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 const LL INF = (1ll<<62); 18 int dp[10][N],p[11]; 19 int d[10]; 20 int dfs(int i,int s,bool e) 21 { 22 if(s<0) return 0; 23 if(i==-1) return 1; 24 if(!e&&dp[i][s]!=-1) return dp[i][s]; 25 int mk = e?d[i]:9; 26 int ans = 0; 27 28 for(int j = 0;j <= mk ; j++) 29 ans+=dfs(i-1,s-j*p[i],e&&j==mk); 30 return e?ans:dp[i][s] = ans; 31 } 32 int cal(int a,int b) 33 { 34 int i,g=0; 35 while(a) 36 { 37 d[g++] = a%10; 38 a/=10; 39 } 40 int s = 0; 41 for(i = 0 ; i < g ; i++) 42 { 43 s+=d[i]*p[i]; 44 } 45 memset(d,0,sizeof(d)); 46 g = 0; 47 while(b) 48 { 49 d[g++] = b%10; 50 b/=10; 51 } 52 return dfs(g-1,s,1); 53 } 54 int main() 55 { 56 int i,t,a,b; 57 int kk = 0; 58 p[0] = 1; 59 for(i = 1 ; i <= 10; i++) 60 p[i] = p[i-1]*2; 61 memset(dp,-1,sizeof(dp)); 62 scanf("%d",&t); 63 while(t--) 64 { 65 scanf("%d%d",&a,&b); 66 printf("Case #%d: %d ",++kk,cal(a,b)); 67 } 68 return 0; 69 }