F(x) HDU

题意:

给你一个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 }
原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11918136.html