HDU 6415 Rikka with Nash Equilibrium (count DP)

Meaning of the questions: Give two integers n, m, let you use all the number 1 ~ n * m, and construct a matrix of n * m matrix, this matrix satisfy: it is only one element is in this row and this column the biggest, seeking a variety of ways.

Analysis: According to the meaning of the questions, you can know that element must be n * m, because this is the largest number, there will be no other possibilities, we consider the order to put the size, the largest first place, and put the second largest, so think about the next largest position where it should be, must be in all the rows or all of the maximum number of columns, because if you do not, then it must also be in its row and column of the largest, and do not condition is satisfied, the same and put the third, but also to put the largest or second largest of all rows or columns in the same way the other as well. Therefore, there is a state equation, dp [i] [j] [k] represent, I have let row number, j the number of columns has been let go, the last number is put k, since the positive and the opposite of the discharge put the result is the same, so we can put a positive, i.e. 1 ~ n * m according to the discharge, transfer equation as follows:

1. Consider first add a new row is selected then all the columns in an already existing, and then select a location in the column (this position is not row and column intersection) will dp [i] [j ] [k] = dp [i-1] [j] [k-1] * j * (n-i + 1)

2. Consider all add to a new one, then that select a row in all the rows have been occurring, and then select a position (this position can not be the intersections of the rows and columns), i.e. dp [i] in the column [ j-1] [k-1] * i * (m-j + 1)

3. Consider placed on the intersections of the rows and columns, dp [i] [j] [k] = dp [i] [j] [k-1] * (i * j-k + 1).

Consider can use the scroll array optimization, of course, can not optimize.

code show as below:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 80 + 7;
int n, m;
int dp[2][maxn][maxn];

int main(){
  int T;  scanf("%d", &T);
  while(T--){
    int K;
    scanf("%d %d %d", &n, &m, &K);
    memset(dp[0], 0, sizeof dp[0]);
    dp[0][1][1] = n * m % K;
    int cur = 1;
    for(int k = 2; k <= n * m; ++k, cur ^= 1){
      memset(dp[cur], 0, sizeof dp[cur]);
      for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j){
          if(i * j < k)  continue;
          dp[cur][i][j] = ((LL)dp[cur^1][i][j] * (i*j-k+1) % K + (LL)dp[cur^1][i-1][j] * j * (n-i+1) % K + (LL)dp[cur^1][i][j-1] * i * (m-j+1)% K) % K;
        }
    }
    printf("%I64d\n", dp[cur^1][n][m]);
  }
  return 0;
}

  

 

Guess you like

Origin www.cnblogs.com/dwtfukgv/p/11502331.html