hdu 4722

来源:互联网 发布:淘宝格子铺免费推广 编辑:程序博客网 时间:2024/06/16 03:37

昨天才学得数位dp,今天刚好网路热身赛遇见一个,而且还比较简单,不过傻X的把dp定义成int没找出错,跪了一小时才发现,不过不得不感叹数位dp真的太适合做类题了,很契合计算机的思想,虽然这种题找规律也可以做,不过既然是编程还是契合计算机思想比较好。

1.数位dp方法:

#include<stdio.h>#include<string.h>#include<stdlib.h> const int max=20;                       int dp[max][10]; int digit[max];long long dfs(int pos,int mod,int flag){    if(pos==-1)return mod==0;                                     if(flag&&dp[pos][mod]!=-1)return dp[pos][mod];    long long sum=0;    int size = flag?9:digit[pos];     for(int i=0;i<=size;i++){        int MOD=(mod+i)%10;        sum+=dfs(pos-1,MOD,flag||i<size);    }    if(flag)dp[pos][mod]=sum;    return sum; } long long cal(long long n){   if(n<0)return 0;        int len = 0;   while(n){       digit[len++] = n%10;//转化成对应的数位        n/=10;   }            return dfs(len-1,0,0);//记忆化搜索 } int main(){   #ifdef T    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);   #endif   long long r,l;   int t;   memset(dp,-1,sizeof(dp));//这里初始化一次就好,每次算的信息还可以供以后用    scanf("%d",&t);   for(int i=1;i<=t;i++){      scanf("%I64d %I64d",&l,&r);      printf("Case #%d: %I64d\n",i,cal(r)-cal(l-1));    }          return 0;} 

2.找规律,例如911,那么肯地有91个数十的取法,最后还得看末尾的个位数与前面的每个digit相加取10的模是否为0,为0还要+1变为92,不过这里好像没有存在+尾数刚好可以得到0的情况所以输出就是91.找规律一定要把所有情况都想到,且处理要普遍化不能太多特例,这样很容易出现某些考虑不到的地方半天找不出错。

#include<cstdio>#include<cstdlib>long long cal(long long num){     long long temp=num;     long long ans=num/10;     int sum=0;     int pre=temp%10;     temp/=10;     while(temp){          sum+=temp%10;          temp/=10;     }     for(int i=0;i<=pre;i++)if((sum+i)%10==0)     {   ans++; break; }     return ans;}int main(){     #ifdef T       freopen("input.txt","r",stdin);       freopen("output.txt","w",stdout);     #endif     long long r,l;     int t;     scanf("%d",&t);     for(int i=1;i<=t;i++){         scanf("%I64d %I64d",&l,&r);         printf("Case #%d: %I64d\n",i,cal(r)-cal(l-1));      }        return 0;} 


原创粉丝点击