这个题叫问给一个2*N的方块,你可以在每一个上填任意黑或者白两种,假设颜色相同的并且有公共边的就被认为是一块,问组成K块有多少种方案。

  这题开始感觉无从下手,像组合数学又不像的,其实这个题的关键在于,2*N 的方块,那么我每两个就只会有四种情况,我们可以通过求最后两位去递推得到更多位数的,因此问题有办法解决了 。

DP[i][j][[k] ,i代表我目前到了第i位置,有j个块,最后一位i是k的情况(我假设 00是0 ,01是1,10是2,11是3)。

PS:DP转移方程太长了,你自己看代码。。。。(其实应该是有更简单的方法的,我的DP写的太丑了)

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
long long dp[1003][2003][4];
const int mod=998244353;
int main(){
   int n,k;
   while(~scanf("%d%d",&n,&k)){
      memset(dp,0,sizeof(dp));
      dp[1][1][0]=1;
      dp[1][2][1]=1;
      dp[1][2][2]=1;
      dp[1][1][3]=1;
      for (int i=1;i<=n;i++){
         for (int j=1;j<=2*n;j++){
            dp[i+1][j][0]=(dp[i+1][j][0]+dp[i][j][0]+dp[i][j][1]+dp[i][j][2])%mod;
            dp[i+1][j+1][0]=(dp[i+1][j+1][0]+dp[i][j][3])%mod;

            dp[i+1][j][1]=(dp[i+1][j][1]+dp[i][j][1])%mod;
            dp[i+1][j+1][1]=(dp[i+1][j+1][1]+dp[i][j][0]+dp[i][j][3])%mod;
            dp[i+1][j+2][1]=(dp[i+1][j+2][1]+dp[i][j][2])%mod;

            dp[i+1][j][2]=(dp[i+1][j][2]+dp[i][j][2])%mod;
            dp[i+1][j+1][2]=(dp[i+1][j+1][2]+dp[i][j][0]+dp[i][j][3])%mod;
            dp[i+1][j+2][2]=(dp[i+1][j+2][2]+dp[i][j][1])%mod;

            dp[i+1][j][3]=(dp[i+1][j][3]+dp[i][j][3]+dp[i][j][1]+dp[i][j][2])%mod;
            dp[i+1][j+1][3]=(dp[i+1][j+1][3]+dp[i][j][0])%mod;
         }
      }

//      for (int i=1;i<=n;i++){
//         for (int j=1;j<=2*n;j++){
//            printf("%d %d %d %d----",dp[i][j][0],dp[i][j][1],dp[i][j][2],dp[i][j][3]);
//         }
//         printf("\n");
//      }
      printf("%lld\n",(dp[n][k][0]+dp[n][k][1]+dp[n][k][2]+dp[n][k][3])%mod);

   }
   return 0;
}