题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6415
dp i,j,k代表
当前已经放置了n-i+1~n个数,剩下的数字不能在j行,k列中放置
③:
1.dpi+1,j,k+1;
2.dpi+1,j+1,k;
3.dpi+1,j,k;
倒着DP时,最后输出DP【n*m】【n】【m】
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define For(i,m,n) for(int i=m;i<=n;i++)
#define Dor(i,m,n) for(int i=m;i>=n;i--)
#define LL long long
#define lan(a,b) memset(a,b,sizeof(a))
#define sqr(a) a*a
using namespace std;
LL dp[6410][85][85];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
//lan(dp,0);
int n,m,mod;
scanf("%d%d%d",&n,&m,&mod);
dp[n*m][n][m]=(LL)n*m%mod;
Dor(i,n*m-1,1)
{
Dor(j,n,1)
Dor(k,m,1)
{
// if(i==1&&j==1&&k==1)
if(j*k<i)
break;
dp[i][j][k]=dp[i+1][j][k]*(j*k-i)%mod;
dp[i][j][k]=(dp[i][j][k]+dp[i+1][j+1][k]*(n-j)*k)%mod;
dp[i][j][k]=(dp[i][j][k]+dp[i+1][j][k+1]*j*(m-k))%mod;
}
}
printf("%lld\n",dp[1][1][1]);
}
return 0;
}
//