版权声明:本文为博主原创文章,喜欢就点个赞吧 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);
}