洛谷P2051 [AHOI2009]中國象棋(動態規劃)
阿新 • • 發佈:2019-01-12
dp[i][j][k]表示放了前i行,有j列是有1個棋子,有k列有兩個棋子
#include <bits/stdc++.h> #include <algorithm> #include <cstdio> #include <iostream> #include <vector> #include <cstdlib> #include<map> using namespace std; typedef long long ll; int n,m; ll mod=9999973; ll dp[110][110][110]; int main() { scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp)); dp[0][0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) for(int k=0;k<=m-j;k++) { dp[i][j][k]+=dp[i-1][j][k]; if(j>=1) dp[i][j][k]+=dp[i-1][j-1][k]*(m-j+1-k);//在沒有的上面加一個 if(k>=1) dp[i][j][k]+=dp[i-1][j+1][k-1]*(j+1);//在有的上面加一個 if(j>=2) dp[i][j][k]+=dp[i-1][j-2][k]*(m-j+2-k)*(m-j+1-k)/2;//兩個沒有的各加一個 if(k>=1) dp[i][j][k]+=dp[i-1][j][k-1]*(m-j-k+1)*j;//一個沒有一個有一個 if(k>=2) dp[i][j][k]+=dp[i-1][j+2][k-2]*(j+2)*(j+1)/2; dp[i][j][k]%=mod; } ll ans=0; for(int i=0;i<=m;i++) for(int j=0;j<=m;j++) { ans+=dp[n][i][j]; ans%=mod; } printf("%lld\n",ans); return 0; }
是有1個棋子,有k列有兩個棋子