zoukankan      html  css  js  c++  java
  • HDU3555 Bomb 数位DP

      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555

    我的DP方程:f[i][j]表示数的第i位以j开头的数含有49的个数,则状态转移方程为:

      1.j!=4时: f[i][j]=sum{ f[i-1][k] | 0<=k<=9 }

          2.j==4时:f[i][j]=sum{ f[i-1][k] | 0<=k<=9 } - f[i-1][9] + pow(10,i-2)  (因为j=4时,只要i-1位为9,后面的都满足)

    这样的转移方程思路比较清晰,在网上看到别人的转移方程是这样的:   

         1.f[i][0]=10*f[i-1][0]-f[i-1][1];           表示不含49的个数
         2.f[i][1]=f[i-1][0];                             表示以9开头不含49的个数
         3.f[i][2]=10*f[i-1][2]+f[i-1][1];          表示含49的个数

    的确比我的优化些,把其它不需要的状态放在一起了。

    DP1:

     1 //STATUS:C++_AC_15MS_288KB
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<queue>
    11 #include<stack>
    12 #include<map>
    13 using namespace std;
    14 #define LL __int64
    15 #define pii pair<int,int>
    16 #define Max(a,b) ((a)>(b)?(a):(b))
    17 #define Min(a,b) ((a)<(b)?(a):(b))
    18 #define mem(a,b) memset(a,b,sizeof(a))
    19 #define lson l,mid,rt<<1
    20 #define rson mid+1,r,rt<<1|1
    21 const int N=65,INF=0x3f3f3f3f,MOD=100000000;
    22 //const double DNF=100000000000;
    23 
    24 LL f[N][11],d[N];
    25 int T;
    26 LL n;
    27 
    28 int main()
    29 {
    30  //   freopen("in.txt","r",stdin);
    31     int i,j,len,num[N],k,la;
    32     LL t,ans;
    33     d[0]=1;
    34     for(i=1;i<20;i++)d[i]=d[i-1]*10;
    35     f[1][4]=1;
    36     for(i=2;i<20;i++){
    37         for(j=0;j<10;j++){
    38             for(k=0;k<10;k++)f[i][j]+=f[i-1][k];
    39             if(j==4){
    40                 f[i][j]-=f[i-1][9];
    41                 f[i][j]+=d[i-1];
    42             }
    43         }
    44     }
    45     scanf("%d",&T);
    46     while(T--)
    47     {
    48         scanf("%I64d",&n);
    49         len=0;ans=0;
    50         do num[len++]=n%10;
    51         while(n/=10);
    52         for(i=len-1,la=-1;i>=0;la=num[i--]){
    53             for(j=num[i]-1;j>=0;j--)
    54                 ans+=f[i][j];
    55             if(num[i]==9 && la==4){
    56                 for(t=1,i--;i>=0;i--)
    57                     t+=num[i]*d[i];
    58                 ans+=t;
    59             }
    60         }
    61 
    62         printf("%I64d\n",ans);
    63     }
    64     return 0;
    65 }

    DP2:

     1 //STATUS:C++_AC_15MS_264KB
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<queue>
    11 #include<stack>
    12 #include<map>
    13 using namespace std;
    14 #define LL __int64
    15 #define pii pair<int,int>
    16 #define Max(a,b) ((a)>(b)?(a):(b))
    17 #define Min(a,b) ((a)<(b)?(a):(b))
    18 #define mem(a,b) memset(a,b,sizeof(a))
    19 #define lson l,mid,rt<<1
    20 #define rson mid+1,r,rt<<1|1
    21 const int N=65,INF=0x3f3f3f3f,MOD=100000000;
    22 //const double DNF=100000000000;
    23 
    24 LL f[N][4],d[N];
    25 int T;
    26 LL n;
    27 
    28 int main()
    29 {
    30  //   freopen("in.txt","r",stdin);
    31     int i,j,len,num[N],k,la;
    32     LL t,ans;
    33     d[0]=1;
    34     for(i=1;i<20;i++)d[i]=d[i-1]*10;
    35     f[0][0]=10;f[0][1]=1;f[0][2]=0;
    36     for(i=1;i<20;i++){
    37         f[i][0]=10*f[i-1][0]-f[i-1][1];
    38         f[i][1]=f[i-1][0];
    39         f[i][2]=10*f[i-1][2]+f[i-1][1];
    40     }
    41     scanf("%d",&T);
    42     while(T--)
    43     {
    44         scanf("%I64d",&n);
    45         len=0;ans=0;
    46         do num[len++]=n%10;
    47         while(n/=10);
    48         for(i=len-1,la=-1;i>=0;la=num[i--]){
    49             if(i>0){
    50                 ans+=num[i]*f[i-1][2];
    51                 if(num[i]>4)ans+=f[i-1][1];
    52             }
    53             if(num[i]==9 && la==4){
    54                 for(t=1,i--;i>=0;i--)
    55                     t+=num[i]*d[i];
    56                 ans+=t;
    57             }
    58         }
    59 
    60         printf("%I64d\n",ans);
    61     }
    62     return 0;
    63 }
  • 相关阅读:
    php lesson1
    微信红包算法java版本
    spring注解
    Java时间戳
    集成环信 服务器端遇见的坑:关于Request body is invalid.解决
    环信java后台发送消息时提示msg 应该为JSONObject 的坑
    jboss设置允许外网访问
    redis实现单点登录
    qq在线客服
    图片纯css控制宽高比
  • 原文地址:https://www.cnblogs.com/zhsl/p/2973389.html
Copyright © 2011-2022 走看看