题意:把2*n的方格,分成m个部分有多少中分法。
在孟神的帮助下看懂了第一道dp,,,,
转自解题报告:
状态表示 f[i][0][j]:前i行已经出现了j部分且第i行的两个格子属于同一部分的方法数
f[i][1][j]:前i行已经出现了j部分且第i行的两个格子属于不同部分的方法数
初始条件 f[1][0][1]=f[1][1][2]=1
状态转移
f[i+1][0][j]=(f[i+1][0][j]+f[i][0][j]+f[i][1][j]*2)%mod;
f[i+1][0][j+1]=(f[i+1][0][j+1]+f[i][0][j]+f[i][1][j])%mod;
f[i+1][1][j]=(f[i+1][1][j]+f[i][1][j])%mod;
f[i+1][1][j+1]=(f[i+1][1][j+1]+f[i][0][j]*2+f[i][1][j]*2)%mod;
f[i+1][1][j+2]=(f[i+1][1][j+2]+f[i][0][j]+f[i][1][j])%mod;
共12种不同的状态转移(见下图)
表示dp 很难,
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<cstdio>
#include<string>
using namespace std;
const int MA=1009;
const int mod=100000007;
int n,m;
int f[MA][2][MA*2];
int main()
{
memset(f,0,sizeof(f));
f[1][0][1]=1;
f[1][1][2]=1;
for(int i=1;i<=1002;i++)
{
for(int j=1;j<=2*i;j++)
{
f[i+1][0][j]=(f[i+1][0][j]+f[i][0][j]+f[i][1][j]*2)%mod;
f[i+1][0][j+1]=(f[i+1][0][j+1]+f[i][0][j]+f[i][1][j])%mod;
f[i+1][1][j]=(f[i+1][1][j]+f[i][1][j])%mod;
f[i+1][1][j+1]=(f[i+1][1][j+1]+f[i][0][j]*2+f[i][1][j]*2)%mod;
f[i+1][1][j+2]=(f[i+1][1][j+2]+f[i][0][j]+f[i][1][j])%mod;
}
}
int cas;
cin>>cas;
while(cas--)
{
scanf("%d%d",&n,&m);
int ans=(f[n][1][m]+f[n][0][m])%mod;
cout<<ans<<endl;
}
return 0;
}