洛谷P4127 [AHOI2009]同類分佈
阿新 • • 發佈:2019-01-07
數位$dp$
這裡我們首先考慮一種做法,就是記錄$f[pos][sum][num]$表示當前是第$pos$位,總的數字和為$sum$,現在的數字是$num$,那麼我們看看下面一行小字,輸入的數位數小於等於$1000$,????一臉懵逼,開個麼大的$f$陣列??於是我們優化一下,我們列舉模數就行了,具體看程式碼:
#include<iostream> #include<cstdio> #include<cstring> #define ll long long #define N 21 using namespace std; int val[N]; ll l,r,mod; ll f[N][207][207]; ll Dfs(int pos,ll sum,ll num,bool limit,bool lead) { if(!pos&!sum) return 0; if(!pos) { if(sum==mod&&!num) return 1; else return 0; } if(!limit&&!lead&&f[pos][sum][num]!=-1) return f[pos][sum][num]; int maxn=limit?val[pos]:9; ll ans=0; for(int i=0;i<=maxn;++i) ans+=Dfs(pos-1,sum+i,(num*10+i)%mod,limit&&(i==maxn),(lead&&!i)); if(!limit&&!lead) f[pos][sum][num]=ans; return ans; } ll Get(ll x) { int len=0; while(x) { val[++len]=x%10; x/=10; } ll ans=0; for(mod=1;mod<=9*len;++mod) { memset(f,-1,sizeof(f)); ans+=Dfs(len,0,0,1,1); } return ans; } int main() { //memset(f,-1,sizeof(f)); scanf("%lld%lld",&l,&r); printf("%lld",Get(r)-Get(l-1)); return 0; }