luogu P2051 [AHOI2009]中国象棋
Posted smyjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P2051 [AHOI2009]中国象棋相关的知识,希望对你有一定的参考价值。
统计方案,果断 dp
注意到合法方案即为每一行,每一列的棋子数不超过2
设(f_{i,j,k})表示放到第(i)行,有(j)列可以放2个,有(k)列可以放1个的方案
然后就随便讨论一下
详见代码
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
//#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=100+10,mod=9999973;
il LL rd()
{
re LL x=0,w=1;re char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
LL f[2][N][N],ans;
int n,m;
int main()
{
n=rd(),m=rd();
int la=0,now=1;f[0][m][0]=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<=m;j++)
for(int k=0;k<=m;k++)
{
if(!f[la][j][k]) continue;
f[now][j][k]=(f[now][j][k]+f[la][j][k])%mod;
if(j-1>=0&&k+1<=m) f[now][j-1][k+1]=(f[now][j-1][k+1]+f[la][j][k]*j)%mod;
if(k-1>=0) f[now][j][k-1]=(f[now][j][k-1]+f[la][j][k]*k)%mod;
if(j-2>=0&&k+2<=m) f[now][j-2][k+2]=(f[now][j-2][k+2]+f[la][j][k]*j*(j-1)/2)%mod;
if(j-1>=0) f[now][j-1][k]=(f[now][j-1][k]+f[la][j][k]*j*k)%mod;
if(k-2>=0) f[now][j][k-2]=(f[now][j][k-2]+f[la][j][k]*k*(k-1)/2)%mod;
f[la][j][k]=0;
}
now^=1,la^=1;
}
for(int j=0;j<=m;j++)
for(int k=0;k<=m;k++)
ans=(ans+f[la][j][k])%mod;
printf("%lld
",ans);
return 0;
}
以上是关于luogu P2051 [AHOI2009]中国象棋的主要内容,如果未能解决你的问题,请参考以下文章
luogu P2051 [AHOI2009]中国象棋 dp 状态压缩+容斥