JZOJ 1667 ( bzoj 1801 ) [ AHOI 2009 ] 中国象棋 —— DP
Posted zinn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZOJ 1667 ( bzoj 1801 ) [ AHOI 2009 ] 中国象棋 —— DP相关的知识,希望对你有一定的参考价值。
题目:https://jzoj.net/senior/#main/show/1667
首先,一行、一列最多只有 2 个炮;
所以记录一下之前有多少行有 0/1/2 个炮,转移即可;
注意取模!小心在某处爆 int 。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const maxn=105,mod=9999973; int n,m,f[maxn][maxn][maxn],ans; ll C(int x){return ((ll)x*(x-1)/2)%mod;} int main() { scanf("%d%d",&n,&m); f[m][0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) for(int l=m-j;l>=0;l--) { int k=m-j-l,tmp=f[j][k][l]; if(!tmp)continue; //1 if(j)(f[j-1][k+1][l]+=(ll)tmp*j)%=mod;//0 -> 1 if(k)(f[j][k-1][l+1]+=(ll)tmp*k)%=mod;//1 -> 2 //2 if(j>1)(f[j-2][k+2][l]+=(ll)tmp*C(j)%mod)%=mod;//0,0 -> 1,1 //%mod if(j&&k)(f[j-1][k][l+1]+=(ll)tmp*j%mod*k%mod)%=mod;//0,1 -> 1,2 //%mod if(k>1)(f[j][k-2][l+2]+=(ll)tmp*C(k)%mod)%=mod;//1,1 -> 2,2 //%mod } for(int j=0;j<=m;j++) for(int k=0;j+k<=m;k++) (ans+=f[j][k][m-j-k])%=mod; printf("%d ",ans); return 0; }
以上是关于JZOJ 1667 ( bzoj 1801 ) [ AHOI 2009 ] 中国象棋 —— DP的主要内容,如果未能解决你的问题,请参考以下文章
bzoj1692 cogs2005 jzoj1940: [Usaco2007 Dec]队列变换