2018.10.25 洛谷P4187 [USACO18JAN]Stamp Painting(計數dp)
阿新 • • 發佈:2018-12-17
傳送門
其實本來想做組合數學的2333.
誰知道是道.
唉只能順手做了
還是用真難則反的思想。 這題我們倒著考慮,只需要求出不合法方案數就行了。 這個顯然是隨便的。 表示到第個格子不合法的方案數。 那麼有兩種情況。
- ,則無論怎麼當前格子染都不合法,
- ,則從當前的格子向左染最多染到第個格子,因此
維護一個動態的字首和來轉移就行了。 程式碼:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
const int N=1e6+5,mod=1e9+7;
int n,m,k,f[N];
int main(){
n=read(),m=read(),k=read();
f[0]=1;
int sum=0,ans=1;
for(int i=1;i<=n;++i)ans=1ll*ans*m%mod;
for(int i=1;i<=n;++i){
if(i<k)f[i]=1ll*f[i-1]*m%mod;
else f[i]=1ll*sum*(m-1)%mod;
sum+=f[i];
if(sum>=mod)sum-=mod;
if(i>=k){
sum- =f[i-k+1];
if(sum<0)sum+=mod;
}
}
ans-=f[n];
if(ans<0)ans+=mod;
cout<<ans;
return 0;
}