题意:给定2*n的巧克力,想把它分成k份,问一共有多少种方法数。
题解:很容易想到dp,因为到最后一行的时候两块巧克力是否属于同一组,考虑dp[i][j][0]代表到i行已经分成j块且最后一行两块属于同一部分的方法数,
dp[i][j][1]代表到i行已经分成j块且最后一行两块不属于同一部分的方法数,一共有12中转移方法:然后预处理出dp后求解。
Sure原创,转载请注明出处。
#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int maxn = 1002;
const int mod = 100000007;
int dp[maxn][maxn << 1][2];
int n,k;
void init()
{
memset(dp,0,sizeof(dp));
dp[1][1][0] = dp[1][2][1] = 1;
for(int i=1;i<1000;i++)
{
for(int j=1;j<2000;j++)
{
dp[i+1][j][0] += dp[i][j][0];
dp[i+1][j][0] %= mod;
dp[i+1][j+1][0] += dp[i][j][0];
dp[i+1][j+1][0] %= mod;
dp[i+1][j+1][1] += (dp[i][j][0] << 1);
dp[i+1][j+1][1] %= mod;
dp[i+1][j+2][1] += dp[i][j][0];
dp[i+1][j+2][1] %= mod;
dp[i+1][j][0] += (dp[i][j][1] << 1);
dp[i+1][j][0] %= mod;
dp[i+1][j][1] += dp[i][j][1];
dp[i+1][j][1] %= mod;
dp[i+1][j+1][0] += dp[i][j][1];
dp[i+1][j+1][0] %= mod;
dp[i+1][j+1][1] += (dp[i][j][1] << 1);
dp[i+1][j+1][1] %= mod;
dp[i+1][j+2][1] += dp[i][j][1];
dp[i+1][j+2][1] %= mod;
}
}
return;
}
void solve()
{
scanf("%d %d",&n,&k);
if(k > (n << 1)) puts("0");
else if(k == (n << 1)) puts("1");
else printf("%d\n",(dp[n][k][0] + dp[n][k][1]) % mod);
return;
}
int main()
{
init();
int cas;
scanf("%d",&cas);
while(cas--)
{
solve();
}
return 0;
}