HDU 4301 Contest 1

开始时设的是第一、二行前i,j列有k种的方法数,但是,这根本转移不了--!

难点在于1,2行的讨论啊。。。

设f[i][j][0]为前i列分成j个部分,且第i列的两个为同一部分的方法数.

f[i][j][1]为前i列分成j个部分,且第i列的两个为不同部分的方法数。

 

于是,很容易就会转到递推方程 了。

f[i+1][j][0]=f[i+1][j][0]+f[i][j][0]+f[i][j][1]*2

f[i+1][j][1]=f[i+1][j][1]+f[i][j][1]

f[i+1][j+1][0]=f[i+1][j+1][0]+f[i][j][0]+f[i][j][1]

f[i+1][j+1][1]=f[i+1][j+1][1]+f[i][j][0]*2+f[i][j][1]*2

f[i+1][j+2][1]=f[i+1][j+2][1]+f[i][j][0]+f[i][j][1]

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MOD 100000007
using namespace std;

int dp[2][2002][2];

int main(){
	int n,k,T;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&k);
		int pt=1;
		memset(dp[1],0,sizeof(dp[1]));
		dp[1][1][0]=dp[1][2][1]=1;
		for(int i=2;i<=n;i++){
			memset(dp[i&1],0,sizeof(dp[i&1]));
			for(int p=1;p<=k;p++){
				dp[i&1][p][0]=(dp[i&1][p][0]+dp[(i-1)&1][p][0]+dp[(i-1)&1][p][1]*2)%MOD;
				dp[i&1][p][1]=(dp[i&1][p][1]+dp[(i-1)&1][p][1])%MOD;
				if(p-1>0){
					dp[i&1][p][0]=(dp[i&1][p][0]+dp[(i-1)&1][p-1][0]+dp[(i-1)&1][p-1][1])%MOD;
					dp[i&1][p][1]=(dp[i&1][p][1]+dp[(i-1)&1][p-1][0]*2+dp[(i-1)&1][p-1][1]*2)%MOD;
				}
				if(p-2>0){
					dp[i&1][p][1]=(dp[i&1][p][1]+dp[(i-1)&1][p-2][0]+dp[(i-1)&1][p-2][1])%MOD;
				}
			}
		}
		int ans=0;
		ans=(ans+dp[n&1][k][0]+dp[n&1][k][1])%MOD;
		printf("%d\n",ans);
	}
	return 0;
}

  

posted @ 2014-10-23 19:30  chenjunjie1994  阅读(168)  评论(0编辑  收藏  举报