BZOJ1833: [ZJOI2010]count 数字计数 (数位dp)

传送门

数位dp... ...大概都是这个套路吧... ...
写这个的时候直接水了一发... ...我也不知道自己写的是不是dp... ...
大概是主要内容和dp关系不大的dp... ...
mark代码..细长的代码真是丑啊..换行太频繁了....
 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 long long a,b;
 9 long long f[15][5]={};
10 int shu[15]={};
11 long long zz[15]={};
12 long long ans[15]={};
13 void doit(long long x,long long fu){
14     memset(shu,0,sizeof(shu));
15     int k=0;
16     long long y=x;
17     while(y){
18         shu[++k]=y%10;
19         y/=10;
20     }
21     long long t;
22     for(int i=1;i<=9;i++){
23         for(int j=k;j>1;j--){
24             if(shu[j]>i){
25                 t=shu[j]*f[j-1][1]+zz[j];
26             }
27             else{
28                 t=shu[j]*f[j-1][1];
29             }
30             ans[i]+=fu*t;
31             if(shu[j]==i){
32                 ans[i]+=(x%zz[j]+1)*fu;
33             }
34         }
35         if(shu[1]>=i){
36             ans[i]+=fu;
37         }
38     }
39     
40     for(int j=k;j>1;j--){
41         if(j==k){
42             t=(shu[j]-1)*f[j-1][1];
43         }
44         else if(shu[j]>0){
45             t=shu[j]*f[j-1][1]+zz[j];
46         }
47         else{
48             t=shu[j]*f[j-1][1];
49         }
50         ans[0]+=fu*t;
51         if(shu[j]==0){
52             ans[0]+=(x%zz[j]+1)*fu;
53         }
54     }
55     if(shu[1]>=0){
56         ans[0]+=fu;
57     }
58     if(k>1){
59         ans[0]+=fu*f[k-1][0];
60     }
61 }
62 int main(){
63     long long t=1;
64     f[0][0]=1;
65     for(int i=1;i<=13;i++){
66         f[i][1]=f[i-1][1]*10+t;
67         f[i][0]=f[i-1][0]+f[i-1][1]*9;
68         zz[i]=t;
69         t*=10;
70     }
71     scanf("%lld%lld",&a,&b);
72     doit(b,1);
73     doit(a-1,-1);
74     for(int i=0;i<9;i++){
75         printf("%lld ",ans[i]);
76     }
77     printf("%lld\n",ans[9]);
78     return 0;
79 }
View Code

 

posted @ 2017-11-04 17:07  鲸头鹳  阅读(138)  评论(0编辑  收藏  举报