• 【AHOI2009】中国象棋 题解(线性DP+数学)


    前言:这题主要是要会设状态,状态找对了问题迎刃而解。

    ---------------------------

    题目描述

    这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!

    输入格式

    一行包含两个整数N,M,之间由一个空格隔开。

    输出格式

    总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。

    数据范围

    100%的数据中N和M均不超过100

    50%的数据中N和M至少有一个数不超过8

    30%的数据中N和M均不超过6

    ----------------------------------------------

    设$f[i][j][k]$表示前$i$行中有$j$列放$1$个棋子,有$k$列放两个棋子的方案数。

    自然而然考虑三种情况:

    1.这一行不放棋子:$f[i][j][k]=f[i-1][j][k]$

    2.这一行放一个棋子:

    (1)选择在没有棋子的一列放一个棋子:$f[i][j][k]+=f[i][j-1][k]*(m-(j-1)-k)$

    (2)选择在有$1$个棋子的一列放一个棋子:$f[i][j][k]+=f[i-1][j+1][k-1]*(j+1)$

    3.这一行放两个棋子:

    (1)$1$个棋子放在有$1$个棋子的一列,$1$个棋子放在没有棋子的一列:$f[i][j][k]+=f[i-1][j][k-1]*j*(m-j-(k-1))$(拥有$1$个棋子的列数是不变的(-1+1),拥有$2$个棋子的列数+1)

    (2)$2$个棋子都放在有$1$个棋子的列上:$f[i][j][k]+=f[i-1][j+2][k-2]*C_{j+2}^2$

    (3)$2$个棋子都放在没有棋子的列上:$f[i][j][k]+=f[i-1][j-2][k]*C_{m-(j-2)-k}^2$

    写的时候考虑边界,最好开$long long$。

    代码:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int mod=9999973;
    int f[110][110][110],n,m,ans;
    int C(int a)
    {
        return (a*(a-1)/2)%mod;
    }
    signed 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<=m-j;k++)
                {
                    f[i][j][k]=f[i-1][j][k];
                    if(k>=1)(f[i][j][k]+=f[i-1][j+1][k-1]*(j+1));
                    if(j>=1)(f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1));
                    if(k>=2)(f[i][j][k]+=f[i-1][j+2][k-2]*(((j+2)*(j+1))/2));
                    if(k>=1)(f[i][j][k]+=f[i-1][j][k-1]*j*(m-j-k+1));
                    if(j>=2)(f[i][j][k]+=f[i-1][j-2][k]*C(m-j-k+2));
                    f[i][j][k]%=mod;
                }
        for (int i=0;i<=m;i++)
            for (int j=0;j<=m;j++) ans=(ans+f[n][i][j])%mod;
        printf("%lld",(ans+mod)%mod);
        return 0;
    }
  • 相关阅读:
    Leetcode 349. Intersection of Two Arrays
    hdu 1016 Prime Ring Problem
    map 树木品种
    油田合并
    函数学习
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 101. Symmetric Tree
    poj 2524 Ubiquitous Religions(宗教信仰)
    pat 1009. 说反话 (20)
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/12990678.html
Copyright © 2020-2023  润新知