1. 程式人生 > >HDU-4389 X mod f(x) && 2018上海大都會邀請賽J 數位dp

HDU-4389 X mod f(x) && 2018上海大都會邀請賽J 數位dp

return %d 一個 cst ide esp display -a pos

題意:給出區間【L,R】,求其中有多少個數滿足自身被數位和整除

比賽出了剛好沒刷的原題系列= =

思路:枚舉的過程中很好記錄數位和,但是一個數字可以很大(1e9、1e12),不能加到狀態裏

既然相對很小的量是數位和,考慮枚舉最終的數位和作為模數,用它來模過程中得到的數字num,這樣num就可以加入狀態了

最後只要枚舉到的數位和確實是這個模數,就是一個可行解,明確狀態之後套模板即可

技術分享圖片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace
std; 5 6 int a[10], dp[10][90][90][90]; 7 8 int dfs(int pos, int sum, int mod, int res, bool lim){ 9 if (pos == -1) return (sum == 0 && res == mod); 10 if (!lim && dp[pos][sum][mod][res] != -1) return dp[pos][sum][mod][res]; 11 int r = lim ? a[pos] : 9; 12 int
ans = 0; 13 for (int i = 0; i <= r; i++){ 14 ans += dfs(pos-1, (sum*10+i)%mod, mod, res+i, lim && i == a[pos]); 15 } 16 if (!lim) dp[pos][sum][mod][res] = ans; 17 return ans; 18 } 19 20 int solve(int x){ 21 int pos = 0; 22 while (x){ 23 a[pos++] = x%10
; 24 x /= 10; 25 } 26 int ans = 0; 27 for (int i = 1; i <= 81; i++) 28 ans += dfs(pos-1, 0, i, 0, 1); 29 return ans; 30 } 31 32 int main(){ 33 int t, a, b, kase = 0; 34 scanf("%d", &t); 35 memset(dp, -1, sizeof dp); 36 while (t--){ 37 scanf("%d%d", &a, &b); 38 printf("Case %d: %d\n", ++kase, solve(b)-solve(a-1)); 39 } 40 return 0; 41 }
View Code

HDU-4389 X mod f(x) && 2018上海大都會邀請賽J 數位dp