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);
	}
}

 

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