HDU 5787 K-wolf Number(数位dp)

http://acm.split.hdu.edu.cn/showproblem.php?pid=5787

题意:
给出一个范围[l,r]和整数k,求出在该范围的数在十进制每k个相邻的数都不同的数的个数。

思路:

看题意就是挺明显的数位dp,一开始不想开5维数组,想用哈希记录状态,不过错了,可能是姿势不太对。。然后就开了5维数组,因为K最多就5嘛,注意好前导0的问题即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const int maxn = 1e6 + 5;
16 
17 ll L,R;
18 int K;
19 int dig[30];
20 ll dp[30][11][11][11][11];
21 
22 bool check(int pre1,int pre2,int pre3,int pre4,int x)
23 {
24     if(K==2)  return x!=pre4;
25     else if(K==3)  return x!=pre4 && x!=pre3;
26     else if(K==4)  return x!=pre4 && x!=pre3 && x!=pre2;
27     else return x!=pre4 && x!=pre3 && x!=pre2 && x!=pre1;
28 }
29 
30 ll dfs(int pos, int pre1, int pre2, int pre3, int pre4, int lead ,int limit)
31 {
32     if(pos==-1)  return lead!=1;
33     if(!limit && dp[pos][pre1][pre2][pre3][pre4]!=-1)  return dp[pos][pre1][pre2][pre3][pre4];
34     int up=limit?dig[pos]:9;
35     ll tmp = 0;
36     for(int i=0;i<=up;i++)
37     {
38         if(lead && i==0)  tmp+=dfs(pos-1,pre1,pre2,pre3,pre4,lead,limit&&i==dig[pos]);
39         else if(check(pre1,pre2,pre3,pre4,i))
40             tmp+=dfs(pos-1,pre2,pre3,pre4,i,0,limit&&i==dig[pos]);
41     }
42     if(!limit)  dp[pos][pre1][pre2][pre3][pre4]=tmp;
43     return tmp;
44 }
45 
46 ll solve(ll x)
47 {
48     int pos=0;
49     while(x)
50     {
51         dig[pos++]=x%10;
52         x/=10;
53     }
54     return dfs(pos-1,10,10,10,10,1,1);
55 }
56 
57 int main()
58 {
59     //freopen("in.txt","r",stdin);
60     while(~scanf("%lld%lld%d",&L,&R,&K))
61     {
62         memset(dp,-1,sizeof(dp));
63         printf("%lld
",solve(R)-solve(L-1));
64     }
65     return 0;
66 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7663614.html