AcWing 1084 数字游戏 II 题解(实体规划—DP—数位DP)

时间:2025-04-18 07:27:25
#include<bits/stdc++.h> using namespace std; const int N = 11, M = 110; int P; int f[N][10][M];//f[i][j][k]表示i位数字,最高位为j,mod N 为 k 的数字的个数 int mod(int x, int y){ return (x % y + y) % y; } void init(){ memset(f, 0, sizeof(f));//因为有多组测试样例,所以每次调用f需要初始化为0 for(int i = 0; i <= 9; i ++ ) f[1][i][i % P] ++ ;// for(int i = 2; i < N; i ++ ){//位数 for(int j = 0; j <= 9; j ++ ){//最高位数字 for(int k = 0; k < P; k ++ ){//mod N 的余数 for(int x = 0; x <= 9; x ++ ){//j-1位数字 f[i][j][k] += f[i - 1][x][mod(k - j, P)]; /* 位数为i,最高位为j,mod N 余数为k的数的个数等于 所有 位数为i - 1,最高位为x,mod N 余数为k-j的数字个数之和 */ } } } } } int dp(int n){ if(!n) return 1; vector<int>num; while(n) num.push_back(n % 10), n /= 10; int res = 0; int last = 0;//表示前面各位数字之和 for(int i = num.size() - 1; i >= 0; i -- ){ int x = num[i]; for(int j = 0; j < x; j ++ ){ res += f[i + 1][j][mod(-last, P)]; /* last 为前i-1位数字之和 所有i+1位,最高位为j,mod N (余数+last)mod N ==0的数都符合 */ } last += x;//last加上第i位数字 if(!i && last % P == 0) res ++ ;//如果所有位都已遍历完,且所有位数上的数字之和mod N 为0,方案数++ } return res; } int main() { int l, r; while(cin>>l>>r>>P){ init(); cout<<dp(r) - dp(l - 1)<<endl; } return 0; }