[AHOI2009]同類分佈

一、題目

點此看題

二、解法

首先肯定想到我們要把數位和放進狀態中,但是原數會有點棘手。

我們可以先枚舉數位和(也就是模數),設dp[i][j][k][l]dp[i][j][k][l],爲前ii位,是否頂到上界,數位和爲kk,餘數爲ll,我們最後要是k=k= 模數,並且l=0l=0,然後就可以轉移了。

#include <cstdio>
#include <cstring>
#define int long long
int read()
{
	int x=0,flag=1;char c;
	while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
	while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*flag;
}
int L,R,cnt,a[20],dp[20][2][200][200],MOD;
int dfs(int pos,bool equal,int sum,int mod)
{
	if(pos==0) return sum==MOD&&mod==0;
	int &t=dp[pos][equal][sum][mod];
	if(t!=-1) return t;
	t=0;
	for(int i=0;i<=9;i++)
	{
		if(equal && i>a[pos]) break;
		t+=dfs(pos-1,equal&&i==a[pos],sum+i,(mod*10+i)%MOD);
	}
	return t;
}
int calc(int num)
{
	int res=0;cnt=0;
	while(num>0) a[++cnt]=num%10,num/=10;
	for(MOD=1;MOD<=cnt*9;MOD++)
	{
		memset(dp,-1,sizeof dp);
		res+=dfs(cnt,1,0,0);
	}
	return res;
}
signed main()
{
	L=read();R=read();
	printf("%lld\n",calc(R)-calc(L-1));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章