【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;
}
posted @ 2020-07-19 10:49  Jayun  阅读(118)  评论(0编辑  收藏  举报