Rikka with Nash EquilibriumTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 341 Accepted Submission(s): 149 Problem Description Nash Equilibrium is an important concept in game theory.Rikka and Yuta are playing a simple matrix game. At the beginning of the game, Rikka shows an n×m integer matrix A . And then Yuta needs to choose an integer in [1,n] , Rikka needs to choose an integer in [1,m] . Let i be Yuta's number and j be Rikka's number, the final score of the game is Ai,j . In the remaining part of this statement, we use (i,j) to denote the strategy of Yuta and Rikka. For example, when n=m=3 and matrix A is ⎡1 1 1 2 4 1 1 3 1⎦ If the strategy is (1,2) , the score will be 2 ; if the strategy is (2,2) , the score will be 4 . A pure strategy Nash equilibrium of this game is a strategy (x,y) which satisfies neither Rikka nor Yuta can make the score higher by changing his(her) strategy unilaterally. Formally, (x,y) is a Nash equilibrium if and only if: {Ax,y≥Ai,y ∀i∈[1,n]Ax,y≥Ax,j ∀j∈[1,m] In the previous example, there are two pure strategy Nash equilibriums: (3,1) and (2,2) . To make the game more interesting, Rikka wants to construct a matrix A for this game which satisfies the following conditions: 1. Each integer in [1,nm] occurs exactly once in A . 2. The game has at most one pure strategy Nash equilibriums. Now, Rikka wants you to count the number of matrixes with size n×m which satisfy the conditions.
Input The first line contains a single integer t(1≤t≤20) , the number of the testcases.
Output For each testcase, output a single line with a single number: the answer modulo K .
Sample Input 2 3 3 100 5 5 2333
Sample Output 64 1170 |
题意:
简化来说,给你一个n和m,要你用数(1,2,3....n*m)构造一个矩阵,这个矩阵必须满足这样一个条件:在整个矩阵中,只有最多一个数是这一行与这一列的最大值。问可以构造多少个这样的矩阵。
做法:
“最多”这个条件可以无视,因为数n*m一定是那一行那一列的最大值,所以简单理解就能得到,我们必须要从大到小的往里面放数字,并且放入的数字必须在已经放数字的行或者列。
通过无脑的暴力打表可以知道知道就是,别问我为什么是这样的,我表示自己都不知道。总感觉是有一种规律还是怎么样的,因为如果我们已经合法的放入(n+m-1)个数的话,那接下来怎么放都没关系。如果有谁知道这个式子怎么样能解释的通了的话,请来告诉我一声哈~
然后就是比较正规的dp了,dp[i][j][k]表示合法放入第k个数的时候,有i行j列已经有数了的情况。具体的代码看下面吧,看了应该就会明白了的。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[85][85][2],ans,mod;
ll n,m;
void init(){
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
dp[i][j][0]=dp[i][j][1]=0;
}
int main(){
int t;
cin>>t;
while(t--){
scanf("%lld%lld%lld",&n,&m,&mod);
init();
dp[1][1][1]=m*n%mod;
int p=1; ans=0;
if(n+m-1==1) ans=m*n%mod;
for(int k=2;k<=n*m;k++){
p^=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j][p]=0;
if(k>i*j)continue;
dp[i][j][p]=(dp[i][j][p]+dp[i][j][p^1]*(i*j-k+1))%mod;
if(i>1) dp[i][j][p]=(dp[i][j][p]+dp[i-1][j][p^1]*(n-i+1)%mod*j%mod)%mod;
if(j>1) dp[i][j][p]=(dp[i][j][p]+dp[i][j-1][p^1]*(m-j+1)%mod*i%mod)%mod;
dp[i][j][p]%=mod;
if(k==n*m){
ans+=dp[i][j][p];
ans%=mod;
}
}
}
}
printf("%lld\n",ans);
}
return 0;
}