Live2d Test Env

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;
}

 

posted @ 2017-12-27 17:19  nimphy  阅读(460)  评论(0编辑  收藏  举报