hdu5787数位dp

Posted Dirge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu5787数位dp相关的知识,希望对你有一定的参考价值。

问:L ~ R有多少个数是K-wolf Number?其中,K-wolf Number的定义是这个数在十进制下,任意相邻的K个字符没有相同的。

dp[i][j][k]表示有i个空位可填,其中不能填j这个数字中所含有的字符,k = true(表示j有前导0)时,还不能填0.

 

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define pii pair<int, int>
 4 #define mp make_pair
 5 #define fi first
 6 #define se second
 7 using namespace std;
 8 const int N = 1e5+5;
 9 ll l, r;
10 int k;
11 ll dp[20][100001][2];
12 int temp[20], tot;
13 
14 ll dfs(int pos, int w, bool tag, bool flag){
15 
16     if(!pos) return 1;
17     if(flag&&~dp[pos][w][tag]) return dp[pos][w][tag];
18     int Max = flag? 9: temp[pos];
19 
20     int ret[5], sum = 0, tmp = w;
21     while(tmp)
22         ret[sum++] = tmp%10, tmp /= 10;
23     if(tag) ret[sum++] = 0;
24 
25     ll ans = 0;
26     for(int i = 0; i <= Max; i++){
27         bool tag2 = true;
28         for(int j = 0; j < sum&&j < k-1; j++)
29             if(ret[j] == i) tag2 = false;
30         if(tag2){
31             tmp = 0;
32             int first = min(k-2, sum-1);
33             for(int j = first; j >= 0; j--)
34                 tmp = tmp*10+ret[j];
35             bool tag3 = false;
36             if(first >= 0&&ret[first] == 0) tag3 = true;
37             ans += dfs(pos-1, tmp*10+i, tag3, flag||i != Max);
38         }
39     }
40     if(flag) dp[pos][w][tag] = ans;
41     //printf("dfs %d, %d, %d, %d %lld\n", pos, w, tag*1, flag*1, ans);
42     return ans;
43 }
44 
45 ll solve(ll x){
46     tot = 0;
47     while(x){
48         temp[++tot] = x%10;
49         x /= 10;
50     }
51     return dfs(tot, 0, 0, 0);
52 }
53 int main(){
54     while(cin >> l >> r >> k){
55         memset(dp, -1, sizeof(dp));
56         ll ans = solve(r)-solve(l-1);
57         cout << ans << endl;
58     }
59     return 0;
60 }

 

以上是关于hdu5787数位dp的主要内容,如果未能解决你的问题,请参考以下文章

hdu5787数位dp

HDU 5787 K-wolf Number(数位dp)

[暑假集训--数位dp]hdu5787 K-wolf Number

HDU 5787 K-wolf Number

HDU 5787 K-wolf Number

数位dp模板