hdu 2089 数位dp

说实在的,有点惭愧,这题,本来想用更好的办法,但是时间复杂度更高了。

朴素的办法就是打表,从1-1000000打一个统计1-n中的合格数的表。

递归枚举其中的数字:

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 using namespace std;
 6 int const N = 20;
 7 int l,r,n,m,num,sl[N],sr[N];
 8 int pow10[8],sl2[N],sr2[N];
 9 int getsum1(int i,int pre,int f)
10 {
11     if(i==0)return 0;
12     int ans=0,up;
13     if(f)up=sl[i];
14     else up=10;
15     for(int j=0;j<up;j++)
16     {
17            if(j==4||(j==2&&pre==6))
18            ans+=pow10[i-1];
19            else
20            ans+=getsum1(i-1,j,0);
21     }
22     if(f)
23     {
24        if(sl[i]==4||(sl[i]==2&&pre==6))ans+=(1+sl2[i-1]);
25        else ans+=getsum1(i-1,sl[i],1);
26     }
27     return ans;
28 }
29 int getsum2(int i,int pre,int f)
30 {
31     if(i==0)return 0;
32     int ans=0,up;
33     if(f)up=sr[i];
34     else up=10;
35     for(int j=0;j<up;j++)
36     {
37            if(j==4||(j==2&&pre==6))
38            ans+=pow10[i-1];
39            else
40            ans+=getsum2(i-1,j,0);
41     }
42     if(f)
43     {
44        if(sr[i]==4||(sr[i]==2&&pre==6))ans+=(1+sr2[i-1]);
45        else ans+=getsum2(i-1,sr[i],1);
46     }
47     return ans;
48 }
49 void pre()
50 {
51     pow10[0]=1;
52     for(int i=1;i<=7;i++)pow10[i]=pow10[i-1]*10;
53 }
54 int main()
55 {
56     pre();
57     while(~scanf("%d %d",&l,&r)&&(l+r)!=0)
58     {
59          l--;
60          n=m=0;
61          num=l;
62          for(;num;num/=10)sl[++n]=num%10;
63          sl2[0]=0;
64          for(int i=1;i<=n;i++)sl2[i]=pow10[i-1]*sl[i]+sl2[i-1];
65          num=r;
66          for(;num;num/=10)sr[++m]=num%10;
67          sr2[0]=0;
68          for(int i=1;i<=m;i++)sr2[i]=pow10[i-1]*sr[i]+sr2[i-1];
69          printf("%d\n",(r-l)-getsum2(m,0,1)+getsum1(n,0,1));
70     }
71     return 0;
72 }

 

最神的还是这位仁兄,看了他的代码,折服了(可以先看看这位牛的)

http://blog.csdn.net/yan_____/article/details/8741726

posted @ 2013-05-04 18:27  诺小J  阅读(143)  评论(0编辑  收藏  举报