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 }