zoukankan      html  css  js  c++  java
  • 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
    ",a,fa);
    55         printf("Case #%d: %d
    ",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
    ",a,fa);
    55         printf("Case #%d: %d
    ",i,solve(b));
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    Microsoft Visual Studio 产品密钥
    ActiveReport 9手把手搭建环境及实战
    TFS 用户与组管理(转)
    FTS下载地址
    URLScan安装及配置(转)
    viewstate加密(转)
    .net 网站发布 Web.Config中的<compilation debug="true"/>
    WebDAV被启用(转)
    js字母大小写转换
    限制同一个用户在同一时间只能登陆一次(转)
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4264121.html
Copyright © 2011-2022 走看看