类型:数位DP
题意:定义一个Good Number 为 一个数所有位数相加的和%10==0.问[A,B]之间有多少Good Number.
方法:
正常“暴力”的定义状态:(i,d,相关量)
定义dp[i][d][mod] 为 d开头的i位数中,%10==mod的数的个数
dp[i][d][mod] = sum(dp[i-1][0~9][(mod-d+10)%10]
出口:dp[1][d][mod] = (d==mod);
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> using namespace std; long long dp[20][10][10]; int num[30]; long long dfs(int i, int d, int mod, bool isQuery) { if (i == 1) return d==mod; if (!isQuery && ~dp[i][d][mod]) return dp[i][d][mod]; long long ans = 0; int end = isQuery?num[i-1]:9; int nextMod = (mod-d+10)%10; for (int j = 0; j <= end; j++) { ans += dfs(i-1, j, nextMod, isQuery && j == end); } if (!isQuery) dp[i][d][mod] = ans; return ans; } long long cal(long long x) { if (x == 0) return 1; if (x == -1) return 0; int len = 0; while (x) { num[++len] = x%10; x/=10; } return dfs(len+1, 0, 0, true); } int main() { int t; cin>>t; int cas = 1; memset(dp, -1, sizeof(dp)); while (t--) { long long a,b ; cin>>a>>b; cout<<"Case #"<<cas++<<": "<<cal(b)-cal(a-1)<<endl; } return 0; }