UVa 1640 The Counting Problem (數位dp)
阿新 • • 發佈:2021-08-15
題目連結:https://acm.hdu.edu.cn/showproblem.php?pid=1663
記錄一下某數字出現的次數,每個數字都單獨算一遍即可
#include<cstdio> #include<cstring> #include<vector> using namespace std; typedef long long ll; const int maxn = 30; int l, r; ll dp[maxn][maxn], ans[maxn]; vector<int> dig; ll dfs(int pos, int num, int ans, int lead, int lim){ if(!pos) { return ans; } if(!lim && !lead && dp[pos][ans] != -1) return dp[pos][ans]; int limit = lim ? dig[pos] : 9; ll res = 0; for(int i = 0 ; i <= limit ; ++i){ if(lead && i == 0) res += dfs(pos-1, num, 0, 1, lim && (i==limit)); else res += dfs(pos-1, num, ans + (i == num), 0, lim && (i==limit)); } if(!lead && !lim) dp[pos][ans] = res; return res; } ll solve(int x, int num){ dig.clear(); memset(dp, -1, sizeof(dp)); dig.push_back(-1); int tmp = x; while(tmp){ dig.push_back(tmp % 10); tmp /= 10; } return dfs(dig.size()-1, num, 0, 1, 1); } ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; } int main(){ while(scanf("%d%d", &l, &r) == 2 && l){ if(l > r) swap(l, r); for(int i = 0 ; i <= 9 ; ++i){ printf("%lld%c", solve(r, i) - solve(l-1, i), i == 9 ? '\n' : ' '); } } return 0; }