Question and question: (a little difficult to read ...)
A sequence of numbers is given to locate a range. When two identical numbers in the interval are deleted, only the sequence between the two numbers is retained, and the same number is deleted, ask how many delete operations can be performed at most.
For example:
Therefore, two delete operations are performed.
Ideas:
The key to interval DP is to determine which small intervals are converted from a large interval.
When a [l] = A [R, DP [l] [r] = DP [L + 1] [r-1] + 1 (because the maximum number of deletions, when the number of large intervals is equal, it must be added by a small internal interval );
When a [l]! = A [R], DP [l] [r] = max (DP [L + 1] [r], DP [l] [r-1]) (This self-simulated ......)
Code:
Length of the inner loop enumeration:
# Include <bits/stdc ++. h> # define INF 0x3f3f3f # define fre () freopen ("in.txt", "r", stdin) using namespace STD; typedef long ll; const int maxn = 5000 + 10; int DP [maxn] [maxn]; int A [maxn]; int main () {// fre (); int N; while (scanf ("% d ", & N )! = EOF) {for (INT I = 1; I <= N; I ++) {scanf ("% d", & A [I]);} for (INT I = 1; I <= N; I ++) {for (Int J = 1; j <= N; j ++) {DP [I] [J] = 0 ;}// memset (DP, 0, sizeof (DP); For (int K = 1; k <N; k ++) {// enumeration Interval Length for (int l = 1; L + k <= N; l ++) {// start point of the enumeration interval if (a [l] = A [L + k]) {DP [l] [L + k] = DP [L + 1] [L + k-1] + 1 ;} else {DP [l] [L + k] = max (DP [L + 1] [L + K], DP [l] [L + k-1]);} printf ("% d \ n", DP [1] [N]);} return 0;}/* Putin: 36 6 6123 14 15 92 65 35 89 79 32 38 46 26123 1 4 1 5 9 2 6 5 3 5 972 7 1 8 8 141 6 1 8111 2 8 16 16 8 4 2 161 2 3 1 2 3 putout: 1022151 */
View code
Right endpoint of the inner cyclic enumeration Interval
# Include <bits/stdc ++. h> # define INF 0x3f3f3f # define fre () freopen ("in.txt", "r", stdin) using namespace STD; typedef long ll; const int maxn = 5e3 + 10; int DP [maxn] [maxn]; int A [maxn]; int main () {// fre (); int N; while (scanf ("% d ", & N )! = EOF) {for (INT I = 1; I <= N; I ++) {scanf ("% d", & A [I]);} for (INT I = 1; I <= N; I ++) {for (Int J = 1; j <= N; j ++) {DP [I] [J] = 0 ;}for (INT L = N; L> = 0; l --) {// start point can only be enumerated in reverse order, for (INT r = L + 1; r <= N; r ++) {if (a [l] = A [R]) {DP [l] [r] = DP [L + 1] [r-1] + 1 ;} else {DP [l] [r] = max (DP [L + 1] [r], DP [l] [r-1]); // DP [l] [r] = max (DP [l] [r-1], DP [l] [r]) ;}} printf ("% d \ n", DP [1] [N]);} return 0 ;}
View code
The interval DP process is roughly the same:
The length of the first-level cyclic enumeration interval, which is the start point of the second-level cyclic enumeration interval.
The second layer has two situations:
First, you need to find a split point K in [st, En] to divide [st, En] into [st, K] and [k + 1, in this way, the two intervals can obtain the optimal solution.
Type 2: [I, j] can be transferred by [I, J-1] or [I, j + 1. This transfer relationship is certainly launched in specific circumstances, not static.
Gym-101670f shooting gallery (CTU open contest 2017 DP)