zoukankan      html  css  js  c++  java
  • [AHOI2009]中国象棋(luogu P2051)

    原题链接:https://www.luogu.org/problem/show?pid=2051

    本题是一道DP,思维难度主要是在多种状态的考虑上。

    对于每一行,最多放两个炮,所以,对于每一行,只会有放一个炮,放两个炮或者不放炮的三种情况

    以f[i][j][k]表示前i行中,有j列有1个炮,k列有两个炮,则有m-j-k列没有炮,a[i]记录C(i,2)。

    1.不放炮:直接将本行的方案数加到下一行即可。

    2.放一个炮,放在一个空列上。要注意空行有m-j-k个,所以要乘上m-j-k再加到下一行

    3.放一个炮,放在一个有一个炮的列上。

    尤其要注意,此时可能没有任何一列只有一个炮的,所以要特判能否进行此次转移。

    4.放两个炮,都放在空列上。空列有(m-j-k)个,而从中选两个放炮,就有C(m-i-j,2)种选法。

    5.放两个炮,分别放在一个空列上和一个只有一个炮的列上,其实相当于在一个空列上放了两个炮,空列有(m-j-k)个,只有一个炮的列有j个。

    6.放两个炮,都放在只有一个炮的列上,首先特判j>=2时才进行转移,有C(j,2)种选法。

    由此,我们就能得到六个转移方程(未特判):

    f[i+1][j][k]+=f[i][j][k];
    f[i+1][j+1][k]+=((f[i][j][k])*(m-k-j))%c;
    f[i+1][j-1][k+1]+=(f[i][j][k]*j)%c;
    f[i+1][j+2][k]+=(f[i][j][k]*a[m-j-k])%c;
    f[i+1][j][k+1]+=(f[i][j][k]*(m-j-k)*j)%c;
    f[i+1][j-2][k+2]+=(f[i][j][k]*a[j])%c;

    转移完成后统计答案,f[i][j][k]中j+k<=m的方案符合要求,加入答案中(j+k>m的情况显然是不合实际的)

    #include<cstdio>
    const int c=9999973; 
    long long ans,f[105][105][105];//前i行j 1,k 2 m-i-j 0
    int n,m,a[105];
    int main()
    {
        scanf("%d %d",&n,&m);
        for(int i=2;i<=100;i++) a[i]=(i*(i-1))/2;
        f[0][0][0]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<=m;j++)
            {
                for(int k=0;k<=m;k++)
                {
                    f[i][j][k]%=c;
                    f[i+1][j][k]+=f[i][j][k];
                    f[i+1][j+1][k]+=((f[i][j][k])*(m-k-j))%c;
                    if(j>0) f[i+1][j-1][k+1]+=(f[i][j][k]*j)%c;
                    f[i+1][j+2][k]+=(f[i][j][k]*a[m-j-k])%c;
                    f[i+1][j][k+1]+=(f[i][j][k]*(m-j-k)*j)%c;
                    if(j>1) f[i+1][j-2][k+2]+=(f[i][j][k]*a[j])%c;
                }
            }
        }
        for(int i=0;i<=m;i++)
        {
            for(int j=0;i+j<=m;j++) ans=(ans+f[n][i][j])%c;
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    [剑指offer] 7. 斐波那契数列
    [剑指offer] 6. 旋转数组的最小数字
    [剑指offer] 5. 用两个栈实现队列
    [剑指offer] 4. 重建二叉树
    [剑指offer] 3. 从头到尾打印链表
    vue.js从输入中的contenteditable元素获取innerhtml
    CSS3 ------- object-fit属性
    mouseenter和mouseover区别
    元素scroll系列属性
    淘宝flexible.js源码分析
  • 原文地址:https://www.cnblogs.com/zeroform/p/7685963.html
Copyright © 2011-2022 走看看