HDU-6415 Rikka with Nash Equilibrium (DP/找規律)

Hormous的一天發表於2018-08-20

Rikka with Nash Equilibrium

題意

定義一個大數為一個矩陣中所在行,所在列的最大值。給出一個N,M,MOD,問可以構造多少矩陣來使得一個矩陣最多隻有一個大數


思路

我們先從最大的數開始考慮,這個數可以放在任意位置,第二大的數則只能放在最大數所在的行或者列,第三大的數則可以有更多的選擇,這樣我們可以列出一個DP方程。

dp[i+1][j][k+1]+=dp[i][j][k](ni)j d p [ i + 1 ] [ j ] [ k + 1 ] + = d p [ i ] [ j ] [ k ] ∗ ( n − i ) ∗ j
<script type="math/tex; mode=display" id="MathJax-Element-1"> dp[i+1][j][k+1] += dp[i][j][k] * (n-i) * j </script>

dp[i][j+1][k+1]+=dp[i][j][k](mj)i d p [ i ] [ j + 1 ] [ k + 1 ] + = d p [ i ] [ j ] [ k ] ∗ ( m − j ) ∗ i
<script type="math/tex; mode=display" id="MathJax-Element-2"> dp[i][j+1][k+1] += dp[i][j][k] * (m-j) * i </script>

dp[i][j][k+1]+=dp[i][j][k](ijk) d p [ i ] [ j ] [ k + 1 ] + = d p [ i ] [ j ] [ k ] ∗ ( i ∗ j − k )
<script type="math/tex; mode=display" id="MathJax-Element-3"> dp[i][j][k+1] += dp[i][j][k] * (i * j-k) </script>


程式碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int dp[83][83][83*83];
int n,m,MOD;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){

        scanf("%d%d%d",&n,&m,&MOD);

        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=i+j-1;k<=i*j;k++) dp[i][j][k] = 0;

        dp[1][1][1]=n*m;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                for(int k=i+j-1;k<=i*j;k++){
                    dp[i+1][j][k+1] = (dp[i+1][j][k+1]+1LL*dp[i][j][k]*(n-i)*j%MOD)%MOD;
                    dp[i][j+1][k+1] = (dp[i][j+1][k+1]+1LL*dp[i][j][k]*(m-j)*i%MOD)%MOD;
                    dp[i][j][k+1]   = (dp[i][j][k+1]  +1LL*dp[i][j][k]*(i*j-k)%MOD)%MOD;
                }
            }
        }

        printf("%d\n",dp[n][m][n*m]);
    }
}

相關文章