【Luogu P4127】[AHOI2009]同类分布

题目大意:

给出两个数 (a,b),求出 ([a,b]) 中各位数字之和能整除原数的数的个数。

正文:

在区间内的计数内问题,考虑到使用 数位DP。

抓住题目大意中的关键词:

求出 ([a,b]) 中各位数字之和整除原数的数的个数。

一般数位DP的状态的隐藏在题目中,因此得出动态规划的状态 (f_{len,sum,mod,pos}) 表示当第 (len) 位各位数字之和为 (sum) 除原数的余是 (mod) 且有没有碰顶时的个数。得到了状态接下来就只是简单的板子了。

代码:


ll dfs(ll len, ll sum, ll x, bool pos)
{
	if(sum + 9 * len < mod) return 0;
	if(!len) return sum == mod && x == 0;
	if((~f[len][sum][x][pos])&& !pos)
		return f[len][sum][x][pos];
	int m = pos ? a[len]: 9;
	ll ans = 0;
	for (int i = 0; i <= m && i + sum <= mod; i++)
	{
		ans += dfs(len - 1, sum + i, (10ll * x + i) % mod, i == a[len] && pos);
	}
	if(!pos) f[len][sum][x][pos] = ans;
	return ans;
	
} 

ll solve(ll n)
{
	memset(a, 0, sizeof(a));
	ll x = n;
	ll len = 0;
	for (; x; x /= 10)a[++len] = x % 10;
	ll ans = 0;
	for (mod = 1; mod <= len * 9; mod ++)
	{
		memset(f, -1, sizeof(f));
		ans += dfs(len, 0, 0, 1);
	}
	return ans;
}
原文地址:https://www.cnblogs.com/GJY-JURUO/p/13338960.html