The second time ~ I began to think is with a greedy DP, who knows the wrong. Later only to understand that violence two points + memory DP
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define LL Long longusing namespace Std;const int inf= (1<<29); int dp[35][35][55];int dfs (int n,int m,int k) {///if (n>m) Swap (n,m ); if (dp[n][m][k]!=-1) {return dp[n][m][k];} if (k>n*m) {Dp[n][m][k]=inf;return INF;} if (k==n*m) {Dp[n][m][k]=0;return 0;} dp[n][m][k]=inf;for (int i=1;i<=m/2;i++) {for (int j=0;j<=min (i*n,k); j + +) {dp[n][m][k]=min (Dp[n][m][k],dfs (n,i , j) +dfs (N,M-I,K-J) +n*n);}} for (int i=1;i<=n/2;i++) {for (int j=0;j<=min (i*m,k); j + +) {dp[n][m][k]=min (Dp[n][m][k],dfs (i,m,j) +dfs (N-i,m, K-J) +m*m);}} return dp[n][m][k];} int main () {int n,m,k; int T; scanf ("%d", &t), memset (Dp,-1,sizeof (DP)); for (int. i=0;i<=30;i++) for (int j=0;j<=30;j++) dp[i][j][0]=0; while (t--) {scanf ("%d%d%d", &n,&m,&k); Ans= (1ll<<60);///if (n>m) swap (n,m); if (dp[n][m][k]==-1) DFS (N,M,K); cout<<dp[n][m][k]<<endl; } return 0;}
CF #EDU R1 E