天天看点

ZOJ 3725 Painting Storages DP+排列计数

              转载于http://blog.csdn.net/zu_xu/article/details/9401497

         采用递推:当N<M时,必不存在满足条件的方法,因而结果为0;N=M时,方案数恰好为1。N>M时,若1到N-1满足条件,则N可以任意染色,方案数为C(N-1)*2;否则,必有1到N-M-1不满足条件,N-M为蓝,N-M+1到N-1为红,这时将N染成红色即可,方案数为2^(N-M-1)-C(N-M-1),即1到N-M-1所有的染色方案数减去满足条件的方案数。

#include <cstdio>
#include <memory.h>
#define mod 1000000007
typedef long long ll;

ll pow2[100000];
ll iter[100001];
int main()
{
    int n, m;
    *pow2 = 1;
    for(int i=1; i<100000; ++i)
        pow2[i] = (pow2[i-1]*2)%mod;
    while(~scanf("%d%d", &n, &m))
    {
        if(n < m)
            printf("0\n");
        else if(n == m)
            printf("1\n");
        else
        {
            memset(iter, 0, m*sizeof(ll));
            iter[m] = 1;
            for(int i=m+1; i<=n; ++i)
                iter[i] = (2*iter[i-1]+pow2[i-m-1]-iter[i-m-1]+mod)%mod;
            printf("%lld\n", iter[n]);
        }
    }
    return 0;
}