POJ 1952 buy low, buy lower dp record data, pojdp
The longest descending subsequence is added to record the number of longest descending subsequences, and then deduplication is required.
The most troublesome thing is to remove duplicates.
The basic idea is: duplicate values are displayed in all cases, and then sub-sequences of the same length exist. Here, the sub-sequence of the DP Record ends with the current value, and you must select the longest descending subsequence of this value, then you need to subtract the subsequence that already exists.
This is a bit of a detour.
For example, 9 8 9 8 2 and 10 5 12 5 3.
If you do not need to record data for this type of questions, you can use the O (nlgn) algorithm, but you do not know how to record data for the moment. Therefore, only DP is used here.
# Include <stdio. h> # include <vector> # include <string. h> # include <algorithm> # include <iostream> # include <string> # include <limits. h >#include <stack >#include <queue> # include <set> # include <map> using namespace std; const int MAX_N = 5001; int arr [MAX_N], N, tbl [MAX_N], C [MAX_N]; void getLongest (int & len, int & n) {memset (tbl, 0, sizeof (int) * (N + 1 )); memset (C, 0, sizeof (int) * (N + 1); tbl [0] = 1; C [0] = 1; (Int I = 1; I <N; I ++) {tbl [I] = 1; for (int j = 0; j <I; j ++) {if (tbl [j] =-1) continue; if (arr [j]> arr [I] & tbl [I] <tbl [j] + 1) {tbl [I] = tbl [j] + 1 ;}} for (int j = 0; j <I; j ++) {if (arr [j]> arr [I] & tbl [I] = tbl [j] + 1) {C [I] + = C [j] ;}} if (C [I] = 0) C [I] = 1; // when incrementing/* you do not need to use the following code for (int j = 0; j <I; j ++) {if (arr [I] = arr [j] & tbl [I] = tbl [j] & C [I] = C [j]) {tbl [I] =-1; break;} // remove the same data 9 8 9 8} if (tbl [I] =-1) continue; */for (int j = 0; j <I; j ++) {if (arr [j] = arr [I] & tbl [j] = tbl [I]) C [I]-= C [j];} // special case: 6 5 7 5 3 need to remove the 5 duplicates} len = INT_MIN; for (int I = 0; I <N; I ++) {len = max (len, tbl [I]);} n = 0; for (int I = 0; I <N; I ++) {if (tbl [I] = len) n + = C [I] ;}} int main () {while (scanf ("% d", & N )! = EOF) {for (int I = 0; I <N; I ++) {scanf ("% d", arr + I);} int len, n; getLongest (len, n); printf ("% d \ n", len, n);} return 0 ;}