HDU - 5787 K-wolf Number 数位dp
Posted cjlhy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 5787 K-wolf Number 数位dp相关的知识,希望对你有一定的参考价值。
直接数位dp就好了。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0) ; using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = (int)1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;} //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int M = (11 * (11 * (11 * (10 * 11 + 10) + 10) + 10) + 10) + 1; LL dp[20][M]; LL L, R, K; int a[N], tot; bool can[N][6]; LL dfs(int p, int mask, bool limit) { if(!can[mask][K]) return 0; if(p == -1) return 1; if(!limit && ~dp[p][mask]) return dp[p][mask]; LL ans = 0; int dn = mask == 0; int up = limit ? a[p] : 9; for(int i = dn; i <= up; i++) { int nmask = 0; if(mask == M - 1 && !i) nmask = mask; else nmask = (mask * 11 + i) % M; ans += dfs(p - 1, nmask, limit && (i == up)); } if(!limit) dp[p][mask] = ans; return ans; } LL solve(LL x) { tot = 0; for(LL i = x; i; i /= 10) { a[tot++] = i % 10; } return dfs(tot - 1, M - 1, 1); } int v[5]; bool vis[10]; bool check(int *v, int k) { memset(vis, 0, sizeof(vis)); for(int i = 0; i + k <= 5; i++) { for(int j = i; j < i + k; j++) { if(v[j] == 10) continue; if(vis[v[j]]) return false; vis[v[j]] = true; } for(int j = i; j < i + k; j++) { if(v[j] == 10) continue; vis[v[j]] = false; } } return true; } int main() { for(v[0] = 0; v[0] <= 10; v[0]++) { for(v[1] = 0; v[1] <= 10; v[1]++) { for(v[2] = 0; v[2] <= 10; v[2]++) { for(v[3] = 0; v[3] <= 10; v[3]++) { for(v[4] = 0; v[4] <= 10; v[4]++) { int x = 0; for(int i = 0; i < 5; i++) { x = x * 11 + v[i]; } for(int k = 2; k <= 5; k++) { can[x][k] = check(v, k); if(!can[x][k]) break; } } } } } } while(scanf("%lld%lld%lld", &L, &R, &K) != EOF) { memset(dp, -1, sizeof(dp)); printf("%lld ", solve(R) - solve(L - 1)); } return 0; } /* */
以上是关于HDU - 5787 K-wolf Number 数位dp的主要内容,如果未能解决你的问题,请参考以下文章