[AHOI2009] 同类分布

题目思路

“具体数字”和“各个数位之和”比较割裂,处理起来十分困难。

不妨固定“各个数位之和”位 \(mod\),在 dfs 时顺便取模,最后要是整除(模后为 \(0\))就记录答案。

AC Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int dp[25][200][200],w[25],mod;
int dfs(int x,int sum,int st,bool lead,bool limit){
	if(!x){
		if(st==0&&sum==mod)	return 1;
		return 0;
	}
	if(!lead&&!limit&&dp[x][sum][st]!=-1)	return dp[x][sum][st];
	int ans=0,up=(limit?w[x]:9);
	for(int i=0;i<=up;i++){
		if(lead&&!i)	ans+=dfs(x-1,sum,(st*10)%mod,1,0);
		else	ans+=dfs(x-1,sum+i,(st*10+i)%mod,0,(limit&&i==up));
	}
	if(!lead&&!limit)	dp[x][sum][st]=ans;
	return ans;
}
int solve(int n){
	int l=0;
	while(n){
		w[++l]=n%10;
		n/=10;
	}
	int ans=0;
	for(mod=1;mod<=l*9;mod++){
		memset(dp,-1,sizeof(dp));
		ans+=dfs(l,0,0,1,1);
	}
	return ans;
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0);
	int a,b;cin>>a>>b;
	cout<<solve(b)-solve(a-1);
	return 0;
}
posted @ 2026-10-06 15:03  深申  阅读(6)  评论(0)    收藏  举报