题意:
给你一个n位的数x(A(n)A(n-1)...A(1)),那么F(x)=A(n)*2^(n-1)+A(n-1)*2^(n-2)......+A(1)*2^(0)
题目输入A、B
你需要找出来在[0,B]这个范围内有多少个数的F(x)大于F(A)
题解:
这个就是卡memset函数的,而且要注意dp方程的选定
注释+正确代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 const int maxn=15; 7 typedef long long ll; 8 ll v[maxn],dp[maxn][200005],standard; 9 ll dfs(ll pos,ll sum,bool limit) 10 { 11 if(sum<0) 12 return 0; 13 if(pos==-1) 14 { 15 return 1; 16 } 17 if(!limit && dp[pos][sum]!=-1) return dp[pos][sum]; 18 ll up=limit?v[pos]:9; 19 ll tmp=0; 20 for(ll i=0; i<=up; ++i) 21 { 22 tmp+=dfs(pos-1,sum-i*(1<<pos),limit && i==v[pos]); 23 } 24 if(!limit) dp[pos][sum]=tmp; 25 return tmp; 26 } 27 ll solve(ll ans) 28 { 29 ll pos=0; 30 while(ans) 31 { 32 v[pos]=ans%10; 33 pos++; 34 ans/=10; 35 } 36 return dfs(pos-1,standard,true); 37 } 38 int main() 39 { 40 ll ans; 41 ll t,n,p=0; 42 scanf("%I64d",&t); 43 memset(dp,-1,sizeof(dp)); 44 //这个题目就是为了卡这个memset,如果memset写在里面就会t 45 //这就限制了你的dp方程只能是 46 //dp[x][y]表示:在第x位,距离限制(就是题目上的F(A))还剩余y个大小 47 while(t--) 48 { 49 50 scanf("%I64d%I64d",&standard,&n); 51 ans=0; 52 ll i=1; 53 while(standard) 54 { 55 ans=ans+(standard%10)*i; 56 i*=2; 57 standard/=10; 58 } 59 standard=ans; 60 //printf("%d ",ans); 61 printf("Case #%I64d: %I64d ",++p,solve(n)); 62 } 63 return 0; 64 }
错误代码+注释:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 const int maxn=15; 7 typedef long long ll; 8 ll v[maxn],dp[maxn][200005],w[maxn],standard; 9 ll dfs(ll pos,ll sum,bool limit) 10 { 11 if(sum>standard) 12 return 0; 13 if(pos==-1) 14 { 15 return 1; 16 } 17 if(!limit && dp[pos][sum]!=-1) return dp[pos][sum]; 18 ll up=limit?v[pos]:9; 19 ll tmp=0; 20 for(ll i=0;i<=up;++i) 21 { 22 tmp+=dfs(pos-1,sum+i*w[pos],limit && i==v[pos]); 23 } 24 if(!limit) dp[pos][sum]=tmp; 25 return tmp; 26 } 27 ll solve(ll ans) 28 { 29 ll pos=0; 30 while(ans) 31 { 32 v[pos]=ans%10; 33 pos++; 34 ans/=10; 35 } 36 return dfs(pos-1,0,true); 37 } 38 int main() 39 { 40 ll ans=1; 41 ll t,n,p=0; 42 w[0]=1; 43 for(ll i=1;i<=15;++i) 44 { 45 ans*=2; 46 w[i]=ans; 47 } 48 scanf("%I64d",&t);memset(dp,-1,sizeof(dp)); 49 while(t--) 50 { 51 52 //memset拿进来结果对但是超时,拿出去结果错 53 // 原因就是我得dp方程没有写好, 54 // 我的dp[x][y]表示:枚举到第x位,现在的大小是多少 55 // 这个样子的话你第一次随便跑一个值比如1 56 // 因为你是要和F(A)作比较才可以,你光知道这个值多大是不能用于下一组数据记忆化搜索的 57 58 scanf("%I64d%I64d",&standard,&n); 59 ans=0; 60 ll i=1; 61 while(standard) 62 { 63 ans=ans+(standard%10)*i; 64 i*=2; 65 standard/=10; 66 } 67 standard=ans; 68 //printf("%d ",ans); 69 printf("Case #%I64d: %I64d ",++p,solve(n)); 70 } 71 return 0; 72 }