排列组合DP,想了半天没有思路,又忍不住偷偷地上网搜了一把。。发现DP这东西思路真是太重要了,想到了状态转移方程的话就几行代码的事情。。想不到的话就OVER。。代码的话基本和别人的差不多,就不废话了,注意第一次取模后要加上模数再取模,因为第一次取模结果有可能是负的,涨姿势了。。
#include<cstdio>
#include<cstring>
int main()
{
int N, M, p[100001], dp[100001];
const int mod = 1000000007;
p[0] = 1;
for (int i = 1; i <= 100000; i++)
p[i] = p[i - 1] * 2 % mod;
while (scanf("%d %d", &N, &M) != EOF)
{
memset(dp, 0, sizeof(dp));
dp[M] = 1;
for (int i = M + 1; i <= N; i++)
dp[i] = ((dp[i - 1] * 2 % mod + p[i - M - 1] - dp[i - M - 1]) % mod
+ mod) % mod;
printf("%d\n", dp[N]);
}
return 0;
}