zoj 3725 DP排列

DP计数,

有限制性条件下的计数无法直接推公式,一般含有重复,无法完全吻合

这时选择dp,调用前面算出的结果

 

(two[i-m-1]-dp[i-m-1])用的妙!

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define ll long long
#define mod 1000000007
#define N 100500

ll two[N];
ll dp[N];
int main ()
{
    ll n,m;
    two[0]=1;
    for(int i=1;i<N;++i)
        two[i]=two[i-1]*2%mod;
    while(scanf("%lld%lld",&n,&m)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        dp[m]=1;
        for(int i=m+1;i<=n;++i)
        {
            dp[i]=2*dp[i-1]+(two[i-m-1]-dp[i-m-1]);
            dp[i]%=mod;
        }
        dp[n]=(dp[n]%mod+mod)%mod;
        printf("%lld\n",dp[n]);
    }
    return 0;
}


你可能感兴趣的:(zoj 3725 DP排列)