# 专题训练之数位DP

1.(HDOJ2089)http://acm.hdu.edu.cn/showproblem.php?pid=2089

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int a[20];
7 int dp[20][2];
8 int dfs(int pos,int pre,int sta,bool limit)
9 {
10     if ( pos==-1 ) return 1;
11     if ( !limit && dp[pos][sta]!=-1 ) return dp[pos][sta];
12     int up=limit?a[pos]:9;
13     int tmp=0;
14     for ( int i=0;i<=up;i++ )
15     {
16         if ( pre==6 && i==2 ) continue;
17         if ( i==4 ) continue;
18         tmp+=dfs(pos-1,i,i==6,limit&&i==a[pos]);
19     }
20     if ( !limit ) dp[pos][sta]=tmp;
21     return tmp;
22 }
23
24 int solve(int x)
25 {
26     int pos=0;
27     while ( x )
28     {
29         a[pos++]=x%10;
30         x/=10;
31     }
32     return dfs(pos-1,-1,0,true);
33 }
34
35 int main()
36 {
37     int l,r;
38     while ( scanf("%d%d",&l,&r)!=EOF && (l+r) )
39     {
40         memset(dp,-1,sizeof(dp));
41         printf("%d\n",solve(r)-solve(l-1));
42     }
43     return 0;
44 }
HDOJ2089

2.(HDOJ3555)http://acm.hdu.edu.cn/showproblem.php?pid=3555

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int a[20];
7 ll dp[20][2];
8 ll dfs(int pos,int pre,int sta,bool limit)
9 {
10     if ( pos==-1 ) return 1;
11     if ( !limit && dp[pos][sta]!=-1 ) return dp[pos][sta];
12     int up=limit?a[pos]:9;
13     ll tmp=0;
14     for ( int i=0;i<=up;i++ )
15     {
16         if ( pre==4 && i==9 ) continue;
17         tmp+=dfs(pos-1,i,i==4,limit&&i==a[pos]);
18     }
19     if ( !limit ) dp[pos][sta]=tmp;
20     return tmp;
21 }
22
23 ll solve(ll x)
24 {
25     int pos=0;
26     while ( x )
27     {
28         a[pos++]=x%10;
29         x/=10;
30     }
31     return dfs(pos-1,-1,0,true);
32 }
33
34 int main()
35 {
36     ll l,r,T;
37     memset(dp,-1,sizeof(dp));
38     scanf("%lld",&T);
39     while ( T-- )
40     {
41         scanf("%lld",&r);
42         printf("%lld\n",r-solve(r)+1);
43     }
44     return 0;
45 }
HDOJ3555

3.(HDOJ4734)http://acm.hdu.edu.cn/showproblem.php?pid=4734

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 const int maxn=10010;
7 int a[12];
8 int dp[12][maxn];
9 int sum;
10 int pow_[maxn];
11
12 int dfs(int pos,int sta,bool limit)
13 {
14     if ( pos==-1 ) return 1;
15     if ( !limit && dp[pos][sta]!=-1 ) return dp[pos][sta];
16     int up=limit?a[pos]:9;
17     int tmp=0;
18     for ( int i=0;i<=up;i++ )
19     {
20         int x=pow_[pos]*i;
21         if ( sta-x<0 ) continue;
22         tmp+=dfs(pos-1,sta-x,limit&&i==a[pos]);
23     }
24     if ( !limit ) dp[pos][sta]=tmp;
25     return tmp;
26 }
27
28 int solve(int x)
29 {
30     int pos=0;
31     while ( x )
32     {
33         a[pos++]=x%10;
34         x/=10;
35     }
36     return dfs(pos-1,sum,true);
37 }
38
39 int main()
40 {
41     int l,r,T,i,j,k,h,A,B,x,y,z,cnt;
42     pow_[0]=1;
43     for ( i=1;i<=8;i++ ) pow_[i]=pow_[i-1]*2;
44     scanf("%d",&T);
45     memset(dp,-1,sizeof(dp));
46     for ( h=1;h<=T;h++ )
47     {
48         scanf("%d%d",&A,&B);
49         sum=0;
50         cnt=0;
51         x=A;
52         while ( x )
53         {
54             y=x%10;
55             sum+=y*pow_[cnt++];
56             x/=10;
57         }
58         printf("Case #%d: %d\n",h,solve(B));
59     }
60     return 0;
61 }
HDOJ4734

4.(POJ3252)http://poj.org/problem?id=3252

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int a[50];
7 ll dp[50][66];
8 ll dfs(int pos,int sta,bool lead,bool limit)
9 {
10     if ( pos==-1 ) return sta>=32;
11     if ( !limit && !lead && dp[pos][sta]!=-1 ) return dp[pos][sta];
12     int up=limit?a[pos]:1;
13     ll tmp=0;
14     for ( int i=0;i<=up;i++ )
15     {
17         else tmp+=dfs(pos-1,sta+(i==0?1:-1),lead && i==0,limit && i==a[pos]);
18     }
19     if ( !limit&&!lead ) dp[pos][sta]=tmp;
20     return tmp;
21 }
22
23 ll solve(ll x)
24 {
25     int pos=0;
26     while ( x )
27     {
28         a[pos++]=x%2;
29         x/=2;
30     }
31     return dfs(pos-1,32,true,true);
32 }
33
34 int main()
35 {
36     ll l,r;
37     memset(dp,-1,sizeof(dp));
38     while ( scanf("%lld%lld",&l,&r)!=EOF )
39     {
40         printf("%lld\n",solve(r)-solve(l-1));
41     }
42     return 0;
43 }
POJ3252

5.(HDOJ5179)http://acm.hdu.edu.cn/showproblem.php?pid=5179

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int a[20];
7 int dp[20][12];
8 int dfs(int pos,int sta,bool lead,bool limit)
9 {
10     if ( pos==-1 ) return 1;
11     if ( !limit && !lead && dp[pos][sta]!=-1 ) return dp[pos][sta];
12     int up=limit?a[pos]:9;
13     int tmp=0;
14     for ( int i=0;i<=up;i++ )
15     {
16         if ( !lead&&i==0 ) continue;
18         {
20             continue;
21         }
22         if ( i>sta&&sta!=-1 ) break;
23         if ( sta%i!=0 && sta!=-1 ) continue;
25     }
26     if ( !limit&&!lead ) dp[pos][sta]=tmp;
27     return tmp;
28 }
29
30 int solve(int x)
31 {
32     int pos=0;
33     while ( x )
34     {
35         a[pos++]=x%10;
36         x/=10;
37     }
38     return dfs(pos-1,-1,true,true);
39 }
40
41 int main()
42 {
43     int l,r,T;
44     scanf("%d",&T);
45     memset(dp,-1,sizeof(dp));
46     while ( T-- )
47     {
48         scanf("%d%d",&l,&r);
49         printf("%d\n",solve(r)-solve(l-1));
50     }
51     return 0;
52 }
HDOJ5179

6.（HDOJ3652）http://acm.hdu.edu.cn/showproblem.php?pid=3652

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int a[20];
7 int dp[20][15][3];
8 int dfs(int pos,int rem,int sta,bool limit)
9 {
10     if ( pos==-1 ) return rem==0&&sta==2;
11     if ( !limit && dp[pos][rem][sta]!=-1 ) return dp[pos][rem][sta];
12     int up=limit?a[pos]:9;
13     int tmp=0;
14     for ( int i=0;i<=up;i++ )
15     {
16         int x=sta;
17         if ( sta==0 && i==1 ) x=1;
18         if ( sta==1 && i!=1 ) x=0;
19         if ( sta==1 && i==3 ) x=2;
20         tmp+=dfs(pos-1,(rem*10+i)%13,x,limit&&i==a[pos]);
21     }
22     if ( !limit ) dp[pos][rem][sta]=tmp;
23     return tmp;
24 }
25
26 int solve(int x)
27 {
28     int pos=0;
29     while ( x )
30     {
31         a[pos++]=x%10;
32         x/=10;
33     }
34     return dfs(pos-1,0,0,true);
35 }
36
37 int main()
38 {
39     int l,r;
40     memset(dp,-1,sizeof(dp));
41     while ( scanf("%d",&r)!=EOF )
42     {
43         printf("%d\n",solve(r));
44     }
45     return 0;
46 }
HDOJ3652

7.（HDOJ3709）http://acm.hdu.edu.cn/showproblem.php?pid=3709

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int a[20];
7 ll dp[20][20][1800];
8 ll dfs(int pos,int bal,int sum,bool limit)
9 {
10     if ( pos==-1 ) return sum==0;
11     if ( !limit && dp[pos][bal][sum]!=-1 ) return dp[pos][bal][sum];
12     int up=limit?a[pos]:9;
13     ll tmp=0;
14     for ( int i=0;i<=up;i++ )
15     {
16         if ( sum+(pos-bal)*i<0 ) continue;
17         tmp+=dfs(pos-1,bal,sum+(pos-bal)*i,limit&&i==a[pos]);
18     }
19     if ( !limit ) dp[pos][bal][sum]=tmp;
20     return tmp;
21 }
22
23 ll solve(ll x)
24 {
25     if ( x==-1 ) return 0;
26     int pos=0;
27     while ( x )
28     {
29         a[pos++]=x%10;
30         x/=10;
31     }
32     ll ans=0;
33     for ( int i=0;i<pos;i++ ) ans+=dfs(pos-1,i,0,true);
34     return ans-pos+1;
35 }
36
37 int main()
38 {
39     ll l,r;
40     int T;
41     memset(dp,-1,sizeof(dp));
42     scanf("%d",&T);
43     while ( T-- )
44     {
45         scanf("%I64d%I64d",&l,&r);
46         printf("%I64d\n",solve(r)-solve(l-1));
47     }
48     return 0;
49 }
HDOJ3709

8.（HDOJ4507）http://acm.hdu.edu.cn/showproblem.php?pid=4507

ans.cnt+=tmp.cnt

ans.sum+=(tmp.sum+tmp.cnt*(i*p[pos]))

ans.sum2+=(tmp.cnt*（(i*p[pos])^2）+2*(i*p[i])*tmp.sum+tmp.sum2)

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 const ll mod=1e9+7;
7 int a[20];
8 ll p[20];
9 struct node{
10     ll cnt,sum,sum2;
11     node(ll _cnt=0,ll _sum=0,ll _sum2=0):cnt(_cnt),sum(_sum),sum2(_sum2) {}
12 }dp[20][10][10];
13
14 node dfs(int pos,int rem,int snum,bool limit)
15 {
16     if ( pos==-1 )
17     {
18         node ss(0,0,0);
19         if ( rem!=0 && snum!=0 ) ss.cnt=1;
20         return ss;
21     }
22     if ( !limit && dp[pos][rem][snum].sum2!=-1 ) return dp[pos][rem][snum];
23     int up=limit?a[pos]:9;
24     node ans(0,0,0);
25     for ( int i=0;i<=up;i++ )
26     {
27         if ( i==7 ) continue;
28         node tmp=dfs(pos-1,(rem*10+i)%7,(snum+i)%7,limit&&i==a[pos]);
29         ans.cnt+=tmp.cnt;
30         ans.cnt%=mod;
31         ans.sum+=(tmp.sum+i*p[pos]%mod*tmp.cnt%mod)%mod;
32         ans.sum%=mod;
33         ans.sum2+=(tmp.sum2+2*p[pos]*i%mod*tmp.sum%mod)%mod;
34         ans.sum2%=mod;
35         ans.sum2+=(tmp.cnt*p[pos]%mod*p[pos]%mod*i*i%mod);
36         ans.sum2%=mod;
37     }
38     if ( !limit ) dp[pos][rem][snum]=ans;
39     return ans;
40 }
41
42 ll solve(ll x)
43 {
44     int pos=0;
45     while ( x )
46     {
47         a[pos++]=x%10;
48         x/=10;
49     }
50     node tmp=dfs(pos-1,0,0,true);
51     return tmp.sum2;
52 }
53
54 int main()
55 {
56     ll l,r;
57     int T;
58     memset(dp,-1,sizeof(dp));
59     p[0]=1;
60     for ( int i=1;i<=18;i++ ) p[i]=(p[i-1]*10)%mod;
61     scanf("%d",&T);
62     while ( T-- )
63     {
64         scanf("%I64d%I64d",&l,&r);
65         printf("%I64d\n",((solve(r)-solve(l-1))%mod+mod)%mod);
66     }
67     return 0;
68 }
HDOJ4507

9.（HDOJ3886）http://acm.hdu.edu.cn/showproblem.php?pid=3886

a、为了确保每个数只被计算一次，当能进入一个新的起伏时，尽量先进入，如果不能再判断是否符合之前的起伏。

b、前导零不应该被算入起伏中，起伏只能在没有前导零的数中匹配。

c、n个运算符至少要有n+1个数。

d、注意开始的状态，第一个数以及第一个运算符。

e、注意大数减一的计算。

f、注意减法的取模。

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 const int maxn=105;
7 const int mod=1e8;
8 char s1[maxn],s2[maxn],op[maxn];
9 int a[maxn];
10 int dp[maxn][12][maxn],len;
11
12 bool check ( int x , int y , char c )
13 {
14     if ( c == '/' &&  x < y ) return true ;
15     if ( c == '-' && x == y ) return true ;
16     if ( c == '\\' && x > y ) return true ;
17     return false ;
18 }
19
20 ll dfs(int pos,int pre,int p,bool lead,bool limit)
21 {
22     if ( pos==-1 ) return p==len;
23     if ( !limit && !lead && dp[pos][pre][p]!=-1 ) return dp[pos][pre][p];
24     int up=limit?a[pos]:9;
25     ll tmp=0;
26     for ( int i=0;i<=up;i++ )
27     {
28
30         else if ( p<len && check(pre,i,op[p+1]) ) tmp=(tmp+dfs(pos-1,i,p+1,lead,limit&&i==a[pos]))%mod;
31         else if ( p>0 && check(pre,i,op[p]) ) tmp=(tmp+dfs(pos-1,i,p,lead,limit&&i==a[pos]))%mod;
32     }
33     if ( !limit&&!lead ) dp[pos][pre][p]=tmp%mod;
34     return tmp;
35 }
36
37 ll solve(char *x,int f)
38 {
39     int i=0,pos=0;
40     int len_=strlen(x);
41     while ( x[i]=='0' ) i++;
42     if ( x[i]=='\0' )  return 0;
43     for( int j=len_-1;j>=i;j-- ) a[pos++]=x[j]-'0';
44     if( f )
45     {
46         a[0]--;
47         for( int j=0;j<pos;j++ )
48         {
49             if(a[j]<0)
50             {
51                 a[j]+=10;
52                 a[j+1]--;
53             }
54         }
55     }
56     pos--;
57     if( a[pos]==0 ) pos--;
58     return dfs(pos,0,0,true,true)%mod;
59 }
60
61 int main()
62 {
63     int l,r;
64     while ( scanf("%s",op+1)!=EOF )
65     {
66         memset(dp,-1,sizeof(dp));
67         len=strlen(op+1);
68         scanf("%s%s",s1,s2);
69         ll r=solve(s2,0);
70         ll l=solve(s1,1);
71         printf("%08lld\n",(r-l+mod)%mod);
72     }
73     return 0;
74 }
HDOJ3886

10.(HDOJ4352)http://acm.hdu.edu.cn/showproblem.php?pid=4352

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int a[25],m;
7 ll dp[25][1030][12];
8
9 int getnews(int x,int s)
10 {
11     for( int i=x;i<=9;i++ )
12         if(s&(1<<i)) return (s^(1<<i))|(1<<x);
13     return s|(1<<x);
14 }
15
16 int count(int x)
17 {
18     int cnt=0;
19     while ( x )
20     {
21         if ( x&1 ) cnt++;
22         x/=2;
23     }
24     return cnt;
25 }
26
27 ll dfs(int pos,int sta,bool lead,bool limit)
28 {
29     if ( pos==-1 ) return count(sta)==m;
30     if ( !limit && !lead && dp[pos][sta][m]!=-1 ) return dp[pos][sta][m];
31     int up=limit?a[pos]:9;
32     ll tmp=0;
33     for ( int i=0;i<=up;i++ )
34     {
36     }
37     if ( !limit&&!lead ) dp[pos][sta][m]=tmp;
38     return tmp;
39 }
40
41 ll solve(ll x)
42 {
43     int pos=0;
44     while ( x )
45     {
46         a[pos++]=x%10;
47         x/=10;
48     }
49     return dfs(pos-1,0,true,true);
50 }
51
52 int main()
53 {
54     ll l,r;
55     int T,h;
56     memset(dp,-1,sizeof(dp));
57     scanf("%d",&T);
58     for ( h=1;h<=T;h++ )
59     {
60         scanf("%lld%lld%d",&l,&r,&m);
61         printf("Case #%d: %lld\n",h,solve(r)-solve(l-1));
62     }
63     return 0;
64 }
HDOJ4352

posted @ 2018-06-05 21:55  HDU_jackyan  阅读(1552)  评论(3编辑  收藏  举报