题目链接
题意
称一个十进制数为漂亮的,如果它取模它各个位的和为 0 。
思路
数位DP,由于各个位之和只可能在0-9*位长,范围较小。
所以枚举一遍各个位之和可能,再用数位DP判断每一种和的数量即可。
DP[pos][mod][num][now],当前位,最终各个位之和,当前各个位之和,当前对mod的余数
dfs(pos,limit,num,now,mod) limit表示当前数有无枚举上界,其他和dp的意义相同
代码
#include <stdio.h>
#include <string.h>
#define ll long long
ll dp[15][120][120][120], a[15];
ll dfs(ll pos, ll limit, ll num, ll now, ll mod)
{
if(pos == -1) return now == 0 && num == mod;
if(!limit && ~dp[pos][mod][num][now]) return dp[pos][mod][num][now];
ll up = limit ? a[pos] : 9, tmp = 0;
for(ll i = 0; i <= up; ++i)
{
if(num + i > mod) continue;
tmp += dfs(pos-1, limit&&i==up, num+i, (now*10+i)%mod, mod);
}
return limit ? tmp : dp[pos][mod][num][now] = tmp;
}
ll solve(ll n)
{
ll pos = 0;
while(n)
{
a[pos++] = n%10;
n /= 10;
}
ll sum = 0;
for(ll i = 1; i <= pos*9; ++i) sum += dfs(pos-1, 1, 0, 0, i);
return sum;
}
int main()
{
ll t, ca = 1;
memset(dp,-1,sizeof(dp));
for(scanf("%lld",&t); ca <= t; ++ca)
{
ll n;
scanf("%lld",&n);
printf("Case %lld: %lld\n",ca,solve(n));
}
return 0;
}