bzoj1801: [Ahoi2009]chess 中国象棋

来源:互联网 发布:淘宝商城三星手机壳 编辑:程序博客网 时间:2024/05/17 07:25

挺好的一个DP题
我们可以知道每行每列只要不超过有2个跑就是和法的

#include<cstdio>#include<cstring>typedef long long LL;const LL N=105;const LL MOD=9999973;LL f[N][N][N];//前i行    有j列是没有棋子的    有k列是有一个棋子的有多少种方案LL n,m; int main(){    memset(f,0,sizeof(f));    scanf("%lld%lld",&n,&m);    f[0][m][0]=1;    for (LL u=1;u<=n;u++)    {        for (LL i=0;i<=m;i++)        {            for (LL j=0;j<=m;j++)            {                f[u][i][j]=f[u][i][j]+f[u-1][i][j];f[u][i][j]%=MOD;                f[u][i][j]=f[u][i][j]+f[u-1][i+1][j-1]*(i+1);f[u][i][j]%=MOD;                f[u][i][j]=f[u][i][j]+f[u-1][i][j+1]*(j+1);f[u][i][j]%=MOD;                f[u][i][j]=f[u][i][j]+f[u-1][i+2][j-2]*(i+2)*(i+1)/2;f[u][i][j]%=MOD;                f[u][i][j]=f[u][i][j]+f[u-1][i][j+2]*(j+2)*(j+1)/2;f[u][i][j]%=MOD;                f[u][i][j]=f[u][i][j]+f[u-1][i+1][j]*(i+1)*j;f[u][i][j]%=MOD;            //  if (f[u][i][j]!=0) printf("%lld %lld %lld %lld\n",u,i,j,f[u][i][j]);            }        }    }    LL ans=0;    for (LL u=0;u<=m;u++)        for (LL i=0;i<=m;i++)            ans=(ans+f[n][u][i])%MOD;    printf("%lld\n",ans);    return 0;}/* 1.不放棋子 2.放一个棋子,放在之前没有棋子的一列 3.放一个棋子,放在之前有一个棋子的一列 4.放两个棋子,放在之前没有棋子的两列 5.放两个棋子,放在之前有一个棋子的两列 6.放两个棋子,分别放在之前没有棋子和有一个棋子的两列*/
原创粉丝点击