HDU 4734——F(x)

三世轮回 提交于 2020-04-04 19:23:11

HDU 4734——F(x)

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4734

题意:数i在0~B的范围内,求F(i)小于F(A)的个数 F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1

先把F(A)算出来=tot,然后按位计算,如果num(当前F(pos)<=tot,方案数+1 返回1,如果num>tot,返回0)

dp[pos][num] 的状态表示为dp[当前第几位][最大值tot-当前f(i)]

上代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 ll a[109];
 5 ll dp[20][10009];
 6 ll tot;
 7 ll dfs(ll pos,ll num,bool limit)
 8 {
 9     if(pos==0) return num<=tot;
10     if(num>tot) return 0;
11     if(!limit&&dp[pos][tot-num]!=-1) return dp[pos][tot-num];
12     ll up=limit?a[pos]:9;
13     ll res=0;
14     for(ll i=0; i<=up; i++)
15     {
16         res+=dfs(pos-1,num+i*(1<<(pos-1)),limit&&i==a[pos]);
17     }
18     if(!limit) dp[pos][tot-num]=res;
19     return res;
20 }
21 ll solve(ll x)
22 {
23     ll pos=0;
24     while(x)
25     {
26         a[++pos]=x%10;
27         x/=10;
28     }
29     return dfs(pos,0,1);
30 }
31 int main()
32 {
33     memset(dp,-1,sizeof(dp));
34     int t;
35     scanf("%d",&t);
36     for(int i=1;i<=t;i++)
37     {
38         ll a,b;
39         scanf("%lld%lld",&a,&b);
40         ll tem=0,cnt=1;
41         tot=0;
42         while(a)
43         {
44             tem=(a%10);
45             tot+=tem*cnt;
46             a/=10;
47             cnt*=2;
48         }
49 //        printf("%lld\n",tot);
50         printf("Case #%d: %lld\n",i,solve(b));
51     }
52     return 0;
53 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!