[AHOI 2009] 同类分布
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1799
[算法]
数位DP
[代码]
#include<bits/stdc++.h> using namespace std; const int MAXS = 162; int i; long long a,b,ans; long long f[20][MAXS + 5][MAXS + 5][2]; inline long long calc(long long x,int p) { int i,j,k,t,len; int a[20]; len = 0; while (x > 0) { a[++len] = x % 10; x /= 10; } reverse(a + 1,a + len + 1); memset(f,0,sizeof(f)); f[0][0][0][1] = 1; for (i = 0; i < len; i++) { for (j = 0; j <= p; j++) { for (k = 0; k < p; k++) { if (!f[i][j][k][0] && !f[i][j][k][1]) continue; for (t = 0; t <= 9; t++) { if (j + t <= p) f[i + 1][j + t][(k * 10 + t) % p][0] += f[i][j][k][0]; if (t < a[i + 1] && j + t <= p) f[i + 1][j + t][(k * 10 + t) % p][0] += f[i][j][k][1]; if (t == a[i + 1] && j + t <= p) f[i + 1][j + t][(k * 10 + t) % p][1] += f[i][j][k][1]; } } } } return f[len][p][0][0] + f[len][p][0][1]; } int main() { scanf("%lld%lld",&a,&b); for (i = 1; i <= MAXS; i++) ans += calc(b,i) - calc(a - 1,i); printf("%lld\n",ans); return 0; }