10 19
3
【约束条件】1 ≤ a ≤ b ≤ 10^18
题意太好理解了,一句话而已。写dfs部分的时候,感觉不要dp了吧,直接深搜暴力深搜就好,结果超时。还是得数位上下手,代码里的求模的那个sum,又学了一手,直接在solve里列出来所有求模的可能性,挨个dfs。
代码如下:
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
int bit[20];
LL dp[20][200][200];
// 数位 模 各位和 1-9*len 上限
LL dfs(int pos, int mod, int sta, int sum, bool limit)
{
if (pos == -1)
{
if (mod == 0 && sta == sum)
return 1;
return 0;
}
if (!limit && dp[pos][mod][sta] != -1)
return dp[pos][mod][sta];
int up = limit ? bit[pos] : 9;
LL temp = 0;
for (int i = 0; i <= up; i++)
{
int mod2 = (mod * 10 + i) % sum;
int sta2 = sta + i;
temp += dfs(pos - 1, mod2, sta2, sum, limit && (i == up));
}
if (!limit)
dp[pos][mod][sta] = temp;
return temp;
}
LL solve(LL x)
{
int pos = 0;
while (x)
{
bit[pos++] = x % 10;
x /= 10;
}
LL ans = 0;
for (int i = 1; i <= pos * 9; i++)
{
memset(dp, -1, sizeof(dp));
ans += dfs(pos - 1, 0, 0, i, 1);
}
return ans;
}
int main()
{
ios::sync_with_stdio(0);
LL le, ri;
while (cin >> le >> ri)
{
cout << solve(ri) - solve(le - 1) << endl;
}
return 0;
}