UVa 11361 Investigating Div-Sum Property (数位dp)
题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2346
唯一的问题就是 \(k\) 太大数组开不下,但发现所有位数之和最多不会超过 \(90\),也就是 \(k\) 大于 \(90\) 一定无解
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 105;
int T, k;
ll A, B;
ll dp[maxn][maxn][maxn][2];
vector<int> dig;
ll dfs(int pos, int sum, int sel, int lim){
if(pos == 0) {
if(sum == 0 && sel == 0) return 1;
else return 0;
}
if(dp[pos][sum][sel][lim] != -1) return dp[pos][sum][sel][lim];
int up = lim ? dig[pos] : 9;
ll res = 0;
for(int i = 0 ; i <= up ; ++i){
res += dfs(pos-1, (sum*10+i)%k, (sel+i)%k, lim & (i == up));
}
dp[pos][sum][sel][lim] = res;
return res;
}
ll solve(ll x){
dig.clear();
memset(dp, -1, sizeof(dp));
dig.push_back(-1);
ll tmp = x;
while(tmp){
dig.push_back(tmp%10);
tmp /= 10;
}
return dfs(dig.size()-1, 0, 0, 1);
}
int main(){
int T;
scanf("%d", &T);
for(int kase = 1 ; kase <= T ; ++kase){
scanf("%lld%lld%d", &A, &B, &k);
if(k > 90) printf("0\n");
else printf("%lld\n", solve(B) - solve(A-1));
}
return 0;
}