这个题叫问给一个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(" "); // } printf("%lld ",(dp[n][k][0]+dp[n][k][1]+dp[n][k][2]+dp[n][k][3])%mod); } return 0; }