hdu 4734 数位dp

给一个数A (十进制表示形式为AnAn-1An-2 ... A2A1,定义函数 F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1,给一个B,求B以内的i,满足F(i)<=F(A)

Sample Input

3
0 100
1 10
5 100
 
Sample Output
Case #1: 1
Case #2: 2
Case #3: 13
 
一开始状态s设置的是前面位数的和,但是这样每次dp对应的值都不同,需要重新清空,浪费了很多时间,于是重新设置s为小于s的数目,这样dp就不用每次重新计算,而达到记忆化搜索的效果,虽然仅仅改了几行代码,但速度快了很多,状态的设置要考虑好

 

TLE代码

 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <algorithm>

 5 #include <cmath>

 6 using namespace std;

 7 int a,b;

 8 int fa;         //fa的值

 9 int dp[10][5000],digit[12];

10 int cal(int n)

11 {

12     int len=1,sum=0;

13     while(n)

14     {

15         sum=sum+(n%10)*(1<<(len-1));

16         len++;

17         n/=10;

18     }

19     return sum;

20 }

21 int dfs(int p,int s,bool e) {   //位数,前面计算的和,任意填

22     if(s>fa)    return 0;

23     if (p==-1) return s<=fa;

24     if (!e &&dp[p][s]!=-1) return dp[p][s];

25     int res = 0;

26     int u = e?digit[p]:9;

27     for (int d=0;d<=u;++d)

28     {

29         int ns=s+d*(1<<p);

30         res+=dfs(p-1,ns,e&&d==u);

31     }

32     return e?res:dp[p][s]=res;

33 }

34 int solve(int n)

35 {

36     int len=0;

37     while(n)

38     {

39         digit[len++]=n%10;

40         n/=10;

41     }

42     return dfs(len-1,0,1);

43 }

44 int main()

45 {

46     int t;

47     //freopen("1.in","r",stdin);

48     scanf("%d",&t);

49     for(int i=1;i<=t;i++)

50     {

51         memset(dp,-1,sizeof(dp));

52         scanf("%d%d",&a,&b);

53         fa=cal(a);

54         //printf("%d %d\n",a,fa);

55         printf("Case #%d: %d\n",i,solve(b));

56     }

57     return 0;

58 }

AC代码:

 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <algorithm>

 5 #include <cmath>

 6 using namespace std;

 7 int a,b;

 8 int fa;         //fa的值

 9 int dp[12][10000],digit[12];

10 int cal(int n)

11 {

12     int len=1,sum=0;

13     while(n)

14     {

15         sum=sum+(n%10)*(1<<(len-1));

16         len++;

17         n/=10;

18     }

19     return sum;

20 }

21 int dfs(int p,int s,bool e) {   //位数,小于s的数量,任意填

22     if (p==-1) return s>=0;

23     if(s<0) return 0;

24     if (!e &&dp[p][s]!=-1) return dp[p][s];

25     int res = 0;

26     int u = e?digit[p]:9;

27     for (int d=0;d<=u;++d)

28     {

29         int ns=s-d*(1<<p);

30         res+=dfs(p-1,ns,e&&d==u);

31     }

32     return e?res:dp[p][s]=res;

33 }

34 int solve(int n)

35 {

36     int len=0;

37     while(n)

38     {

39         digit[len++]=n%10;

40         n/=10;

41     }

42     return dfs(len-1,fa,1);

43 }

44 int main()

45 {

46     int t;

47     //freopen("1.in","r",stdin);

48     scanf("%d",&t);

49     memset(dp,-1,sizeof(dp));

50     for(int i=1;i<=t;i++)

51     {

52         scanf("%d%d",&a,&b);

53         fa=cal(a);

54         //printf("%d %d\n",a,fa);

55         printf("Case #%d: %d\n",i,solve(b));

56     }

57     return 0;

58 }

 

你可能感兴趣的:(HDU)