hdu 6415 - DP

a1214034447發表於2018-08-23

題目連結:點選這裡

 

解題思路:

根據題意我們很容易想到納什均衡點就在n*m的值的位置

我們現在從大到小來放這些數。假設1位置是第一個數放的位置。那麼接下來第二個數肯定只能放在紅色線上除了1以外的任意地方。假設他放在了2的位置。那麼第三個數就會又多出黃色那條線的選擇。

圖中也很容易看出點肯定是放在現在這個狀態的交叉點上面。並且i行橫線j行豎線的交叉點數是i*j

原有的問題就可以轉化成在n條長為m的橫線和m條長為n的豎線上面放n*m個點的方案數。

另dp[i][j[k]表示在i個橫線j個豎線上放k個數的方案數。

那麼它的轉移途徑就有三種:

dp[i-1][j][k-1] -> dp[i][j[k],在新生成的一個橫線中放第k個數

dp[i][j-1][k-1] -> dp[i][j[k],在新生成的一個豎線中放第k個數

dp[i][j][k-1] -> dp[i][j[k],在還剩下沒放的交叉點中放第k個數

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mx = 81;
int n,m,mod;
ll dp[mx][mx][mx*mx];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&mod);
        dp[1][1][1] = n*m%mod;
        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) continue;
                    dp[i][j][k] = dp[i-1][j][k-1]*j*(n-i+1)%mod;
                    dp[i][j][k] = (dp[i][j][k]+dp[i][j-1][k-1]*i*(m-j+1)%mod)%mod;
                    dp[i][j][k] = (dp[i][j][k]+dp[i][j][k-1]*(i*j-k+1)%mod)%mod;
                }
            }
        }
        printf("%lld\n",dp[n][m][n*m]);
    } 
    return 0;     
} 

 

相關文章