2018.10.05 bzoj1801: [Ahoi2009]chess 中國象棋(狀壓dp)
阿新 • • 發佈:2018-12-13
傳送門 dp好題。 定義狀態表示前i行,有j行放一個棋子,k行放兩個棋子。 然後分當前放個棋子轉移。 程式碼:
#include<bits/stdc++.h>
#define mod 9999973
#define ll long long
using namespace std;
int n,m;
ll f[105][105][105];
int main(){
scanf("%d%d",&n,&m);
f[0][0][0]=1;
for(int i=1;i<=n;++i){
for(int j=0;j<= m;++j){
for(int k=0;k+j<=m;++k){
f[i][j][k]=f[i-1][j][k];
if(k){
(f[i][j][k]+=f[i-1][j+1][k-1]*(j+1)%mod)%=mod;
if(k>=2)(f[i][j][k]+=f[i-1][j+2][k-2]*((j+2)*(j+1)/2)%mod)%=mod;
(f[i][j][k]+=f[i-1][j][k-1]*(m-j-k+1)%mod*j%mod)%=mod;
}
if(j>=2)(f[i][j][k]+=f[i- 1][j-2][k]*((m-j-k+2)*(m-j-k+1)/2)%mod)%=mod;
if(j)(f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1)%mod)%=mod;
}
}
}
ll ans=0;
for(int i=0;i<=m;++i)for(int j=0;j+i<=m;++j)(ans+=f[n][i][j])%=mod;
printf("%lld",ans);
return 0;
}