Q: N row m column of the grid cake with some cherries, each time you can use a knife to cut along the grid line into two pieces, asked to make the final cake on each piece happens to have a cherry, cut to the minimum length.
Straight forward to think how to cut feel bad, but you can, in turn, like the interval splicing the same consideration when a mesh cake stitching up, stitching the length is to cut the length.
Dp[a][b][c][d] represents the shortest length of stitching from (A, b) to the rectangular range (c, D), Num[a][b][c][d] used to count the number of cherries in the rectangular area. If there is only one (or no) cherry in this area, then the stitching length must be 0. For a region can be up or down two rectangles can also be the left and right two rectangular stitching, then enumerate the location of the stitching can be, note if the stitching of the two rectangle has a no cherry is not eligible, to skip.
The whole idea is consistent with the interval DP, but the interval DP is one-dimensional, and this one is two-dimensional.
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> using namespace
Std
int dp[21][21][21][21];
int num[21][21][21][21];
int main () {int KS = 1, n, M, Q, R, C;
while (~SCANF ("%d%d%d", &n, &m, &q)) {memset (num, 0, sizeof (num));
Memset (DP, 0x3f, sizeof (DP));
while (q--) {scanf ("%d%d", &r, &c);
NUM[R-1][C-1][R][C] = 1; for (int RL = 1; RL <= N; rl++) {for (int cl = 1; CL <= m. cl++) {for (int br = 0; BR + RL <= N; br++) {for (int bc = 0; BC + CL <= m; bc++) {int er = BR + RL, EC = BC + C
L NUM[BR][BC][ER][EC] = max (NUM[BR][BC][BR + 1][ec] + num[br + 1][bc][er][ec], NUM[BR][BC][ER][BC + 1] + NUM[BR][BC + 1][er]
[EC]);
printf ("%d%d%d%d\n", BR, BC, er, EC, num[br][bc][er][ec]); if (num[BR] [BC] [ER]
[EC] <= 1) {Dp[br][bc][er][ec] = 0;
Continue for (int j = br + 1; j < er; j + +) {if (!num[br][bc][j][ec] | |!num [j] [BC] [ER] [EC])
Continue if (Dp[br][bc][j][ec] + DP[J][BC][ER][EC] + CL < Dp[br][bc][er][ec]) {DP[BR][BC][ER][EC
] = Dp[br][bc][j][ec] + DP[J][BC][ER][EC] + cl; for (int j = BC + 1; j < EC; J + +) {if (! NUM[BR][BC][ER][J] | |
!NUM[BR][J][ER][EC]) continue; if (Dp[br][bc][er][ec] > Dp[br][bc][er][j] + dp[br][j][er][ec] + RL) DP[BR][BC][ER][EC]
= Dp[br][bc][er][j] + DP[BR][J][ER][EC] + RL; printf (case%)}}}D:%d\n ", ks++, Dp[0][0][n][m]);
return 0;
/** 3 4 3 1 2 2 3 3 2 **/