2018 Multi-University Training Contest 9--HDU 6415 Rikka with Nash Equilibrium

题意:

有一种由[1, n*m]不重复填充的矩阵,并且只有一个点在行和列上是最大的。求这种 n*m 矩阵有多少种。

题解:

最大值一定是 n*m,我们可以把他放在任意格子,但是我们可以发现,无论放在哪里他的矩阵都可以变形会最大值在(1,1)的情况。

9 8 7
6 5 4
3 2 1
1 3 2  
7 9 8 7
4 6 5 4
  3 2 1

所以我们计算出最大值在(1,1)的情况在乘上 n*m。

我们用 dp[k][i][j] 来保存矩阵个数(i 表示可以用的行数,j 表示可以用的列数,k 表示已经填好的数字)

假设最大值是 9:

9 在(1,1)接下来就是放 8 ,现在我们可以知道在第一行和第一列可以放(因为最大值是 9 ,可以压制 8),所以如果把 8 放在第一行就有 m-1 个格子可以放,即 (m-1)*dp[1][1][1];如果把 8 放在第一列就有 n-1 个格子可以放,即 (n-1)*dp[1][1][1];这样我们就得到 dp[2][2][1] = 2, dp[2][1][2] = 2。

接下来就放7,现在由上一步可以知道我们可以知道有 2 行 2 列可以放,像上一步可以通过放在外围多加一行和多加一列,即:dp[3][3][1] = (m-2)*dp[2][2][1] = 2;dp[3][1][3] = (m-2)*dp[2][1][2] = 2。由于上次我们填 8 时可以用的 2 行 2 列也是可以填 7 的,条件就是 i * j > k-1 未填满矩阵,所以 dp[3][2][2] = (i * j - k + 1) * dp[2][2][2] +  (m - j + 1 ) * i * dp[2][2][1] + (n - i + 1) * j * dp[2][1][2]= 16(dp[2][2][2] 初始化的时候是 0 ,因为放 8 根本不可以放在(2,2))。

所以 dp 公式就是:

当 i * j > k - 1时,dp[k][i][j] = (i * j- k + 1) * dp[k+1][i][j] +  (m - j + 1) * i * dp[k-1][i][j-1] + (n - i + 1) * j * dp[k][i-1][j]。

AC代码:

#include <algorithm>
#include  <iostream>
#include   <cstdlib>
#include   <cstring>
#include    <cstdio>
#include    <string>
#include    <vector>
#include    <bitset>
#include     <stack>
#include     <cmath>
#include     <deque>
#include     <queue>
#include      <list>
#include       <set>
#include       <map>
#define mem(a, b) memset(a, b, sizeof(a))
#define pi acos(-1)
using namespace std;
typedef long long ll;

ll n, m, mod;
ll dp[6410][85][85];

ll work(){
	for(int k = 2; k <= n*m; k++){
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){
				if(i*j > k-1){
					dp[k][i][j] = dp[k-1][i-1][j]*(n-i+1)*j % mod;
					dp[k][i][j] = (dp[k][i][j]+dp[k-1][i][j-1]*(m-j+1)*i%mod) % mod;
					dp[k][i][j] = (dp[k][i][j]+dp[k-1][i][j]*(i*j-k+1)%mod) % mod;
				}
			}
		}
	}
	return dp[n*m][n][m];
}

int main(){
	int t;
	scanf("%d", &t);
	while(t--){
		scanf("%lld %lld %lld", &n, &m, &mod);
		dp[1][1][1] = 1;
		printf("%lld\n", work()*n*m%mod);
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章