HihoCoder1651 : 小球染色([Offer收割]编程练习赛38)(DP的优化)
描述
小Ho面前有N个小球排成了一排。每个小球可以被染成M种颜色之一。
为了增强视觉效果,小Ho希望不存在连续K个或者K个以上的小球颜色一样。
你能帮小Ho计算出一共有多少种不同的染色方法么?
例如N=4, M=2, K=3,则有10种染色方法:
0010 0011 0100 0101 0110 1001 1010 1011 1100 1101
输入
三个整数:N, M和K。
对于30%的数据, 1 ≤ N, M, K ≤ 100
对于60%的数据,1 ≤ N, M, K ≤ 300
对于100%的数据,1 ≤ N, M, K ≤ 1000
输出
一个整数表示答案。注意方法数可能非常大,你只需要输出模1000000007的结果。
样例输入
4 2 3
样例输出
10
我猜大部分人是用O(n^2)的DP做的,我是O(n)嘻嘻,大数据轻轻松松。。。
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int max(int a,int b) {if(a>b) return a;return b;} const int Mod=1000000007; long long dp[1010],sum[1010]; int main() { int n,m,k,i,j; scanf("%d%d%d",&n,&m,&k);k--; for(i=1;i<=n;i++){ int tmp=max(1,i-k); if(i-1>=tmp) dp[i]=((sum[i-1]-sum[tmp-1])%Mod+Mod)%Mod*(m-1); if(i-k<=0) dp[i]+=m; sum[i]=(sum[i-1]+dp[i])%Mod; } printf("%lld\n",dp[n]%Mod); return 0; }
It is your time to fight!