[题解]luogu_P4127_同类分布(数位dp
如果像普通数位dp一样记的话我们需要知道这个数最后的数位和,然而我们并不能把它记到状态里,但是他的范围在18*9以内,所以枚举一下最后这个数的数位和,每次只统计数位和等于这个数的答案
还有就是有时候把前导0和lmt记到数组里会死,可能是我写挂了
#include<bits/stdc++.h> #define ll long long using namespace std; ll a,b; ll f[20][200][200],num[20];//到i位数字和为j取余为k ll M;//枚举的模数 ll dfs(int pos,int sum,int mod,bool lmt){ if(pos==0)return (mod==0&&sum==M); if(!lmt&&f[pos][sum][mod]!=-1)return f[pos][sum][mod]; int top=lmt?num[pos]:9; ll ans=0; for(int i=0;i<=top;i++) ans+=dfs(pos-1,sum+i,(mod*10+i)%M,lmt&&i==top); if(!lmt)f[pos][sum][mod]=ans; return ans; } ll work(ll x){ ll tmp=x,cnt=0; while(tmp){ num[++cnt]=tmp%10; tmp/=10; } ll ans=0; for(int i=1;i<=cnt*9;i++){ memset(f,-1,sizeof(f)); M=i; ans+=dfs(cnt,0,0,1); } return ans; } int main(){ scanf("%lld%lld",&a,&b); printf("%lld",work(b)-work(a-1)); }