HDU 6415 Rikka with Nash Equilibrium 【dp + 思维】 多校

版权声明:本文为博主原创文章,喜欢就点个赞吧 https://blog.csdn.net/Anxdada/article/details/81908714

传送门

题意: 在一个矩阵中,如果某一个数字是该行该列的最大值,则这个数满足纳什均衡。
要求构造一个n*m的矩阵,里面填的数字各不相同且范围是【1,n*m】,并且这个矩阵只能有一个纳什均衡, 问有多少种构造方案

思路: 因为这个和最大值有关, 所以我们考虑从大到小放. 从大到小一个个放数字进去,每放进去一个数字,它的这一行这一列就被占领(这一行这一列就可以放数字了). 可以发现每放进去一个数字会有三种状态:
1、多占领一行;
2、多占领一列;
3、没有多占领。即处在原先占领行列的交叉口

然后进行dp的转移即可. dp[i][j][k] 代表放了第i个数字后占领了j行k列的方案数. 最后答案就是dp[n*m][n][m]。 注意要有优化才行,否则很容易T. 具体优化我写在代码中, 注意查看即可.

AC Code

int dp[6405][82][82];
int mod;
void add(int &x, ll y) {
    x = (1ll*x+y) % mod;
}
int n, m;
void solve() {
    scanf("%d%d%d", &n, &m, &mod);
    dp[1][1][1] = n*m;
    for (int j = 1 ; j <= n ; j ++) {
        for (int k = 1 ; k <= m ; k ++) {
            for (int i = 2 ; i <= j*k ; i ++) {
                // i根据和j*k的关系放内层循环, 2000ms左右AC
                dp[i][j][k] = 0; // 里面清零
                add(dp[i][j][k], 1ll*dp[i-1][j-1][k]*(n-j+1)*k);
                add(dp[i][j][k], 1ll*dp[i-1][j][k-1]*(m-k+1)*j);
                add(dp[i][j][k], 1ll*dp[i-1][j][k]*(j*k-i+1));
            }
        }
    }
    printf("%d\n", dp[n*m][n][m] % mod);
}

猜你喜欢

转载自blog.csdn.net/Anxdada/article/details/81908714
今日推荐