题意
求有多少种棋盘使得每一列和每一行的棋子个数不超过 \(2\) 个。
思路
设计 \(f_{i,j,k}\) 表示前 \(i\) 行,有 \(j\) 列为 \(1\) 个棋子,\(k\) 列为 \(0\) 个棋子。
- 考虑当前行放 \(0\) 个棋子,则有 \(f_{i,j,k} = f_{i-1,j,k}\)。
- 若当前行放 \(1\) 个棋子,一种可能是放在 \(1\) 的列,另一种可能是放在 \(0\) 的列。
- 若当前行放 \(2\) 个棋子,可以两个都放 \(0\),或者两个都放 \(1\),或者一个放 \(0\) 一个放 \(1\)。
对应的情况要乘对应的排列系数,比较显然就不再赘述。
code
#include<bits/stdc++.h>
#define ll long longusing namespace std;const ll N = 105,mod = 9999973,inv = 4999987;int n,m;
ll dp[N][N][N];
void add(ll &x,ll y){(x+=y)%=mod;
}
int main() {cin>>n>>m;ll ans=0;dp[0][0][m]=1;for(int i=1;i<=n;i++){for(int j=0;j<=m;j++){for(int k=0;k<=m-j;k++){ll &res=dp[i][j][k];add(res,dp[i-1][j][k]);add(res,dp[i-1][j+1][k]*(j+1)%mod);if(j)add(res,dp[i-1][j-1][k+1]*(k+1)%mod);if(j>=2)add(res,dp[i-1][j-2][k+2]*(k+2)%mod*(k+1)%mod*inv%mod);add(res,dp[i-1][j+2][k]*(j+2)%mod*(j+1)%mod*inv%mod);
// add(res,dp[i-1][j][k+1]*(k+1)%mod);add(res,dp[i-1][j][k+1]*(k+1)%mod*j%mod);if(i==n)ans=(ans+res)%mod;}}}cout<<ans;return 0;
}