Note that we need to construct two endpoints and then directly open up the DP [I] [J] State to indicate the minimum number of gold coins rescued by prisoners between I and j, note that the boundary I and j are not retrieved at this time. The initial condition is DP [I] [I + 1] = 0.
The Code is as follows:
# Include <cstring> # include <cstdlib> # include <cstdio> # include <iostream> using namespace STD; const int INF = 0x3fffffff; int N, P, Loc [105], DP [105] [105]; int DFS (int A, int B) {If (B-A = 1) return 0; If (DP [a] [B]) return DP [a] [B]; int ret = inf; For (INT c = a + 1; C <B; C ++) {ret = min (Ret, DFS (a, c) + DFS (C, B) + (loc [B]-loc [a])-2);} DP [a] [B] = ret; return ret;} int main () {int T, CA = 1; for (scanf ("% d", & T); Ca <= T; ++ CA) {scanf ("% d", & N, & P); loc [0] = 0; loc [p + 1] = n + 1; for (INT I = 1; I <= P; ++ I) {scanf ("% d", & loc [I]); // record prisoner location} p + = 1; memset (DP, 0, sizeof (DP);/* For (INT Gap = 2; Gap <= P; gap ++) {for (int A = 0; A + gap <= P; A ++) {int B = a + gap; int ret = inf; for (INT c = a + 1; C <B; C ++) {ret = min (Ret, DP [a] [c] + dp [C] [B] + (loc [B]-loc [a]-2 ));} DP [a] [B] = ret;} * // printf ("case # % d: % d \ n", CA, DP [0] [p]); printf ("case # % d: % d \ n", CA, DFS (0, P);} return 0 ;}