From http://blog.csdn.net/zhang360896270/article/details/6701589
This requires the maximum length and number of sub-sequences to be dropped. we can add the array maxlen [size] (record the maximum length of the descending sequence between the current 1st points and the I point) and maxnum [size] (Record 1 ~ The maximum number of descent sequences between I). First, for the longest descent sequence, it is a basic DP question. As long as each a [I] is obtained to meet the requirements (a [I] <A [J]) maxlen [J] + 1 ).
In the sequence, if maxlen [J] + 1 = maxlen [I], it means that a [I] And a [J] are in the same descent sequence, so we only need to transfer each qualified state maxnum [J] To maxnum [I]. There are several details that need to be noted that the question sequence is strictly decreasing, so we can only record one legal solution for two identical numbers, so the program must only record the state between two identical numbers. Here, we can simplify programming by using reverse push, as long as an equal value is found, the loop jumps out directly. Note that if the same a [J] is found from the current A [I], there is no feasible state between them, when the default value of maxnum [I] is 1, it must be changed to 0 (to avoid miscalculation). If the value is 0, no processing is required.
#include <iostream>#include <string.h>#include <cstdio>using namespace std;const int size = 5100;int maxlen[size];//记录当前第1个点到第i个点之间的最长下降序列长度int maxnum[size];//记录1~i之间的最长下降序列个数int main(){ //freopen("in.txt","r",stdin); int a[size]; int n; while (scanf("%d", &n) != EOF){ for (int i = 1; i <= n; i ++){ scanf("%d", &a[i]); maxnum[i] = 0; maxlen[i] = 1; } for (int i = 1 ; i <= n; i ++){ for (int j = 1; j < i; j ++){ if (a[i] < a[j]){ maxlen[i] = max(maxlen[i], maxlen[j]+1); } } } for (int i = 1; i <= n; i ++) if (maxlen[i] == 1)maxnum[i] = 1; for (int i = 1; i <= n; i ++){ for (int j = i-1; j > 0; j --){ if (a[j] > a[i]){ if (maxlen[j]+1 == maxlen[i]){ maxnum[i] += maxnum[j]; } } if (a[j] == a[i]){ if (maxlen[i] == 1)maxnum[i] = 0;//如果搜索到一个相同的数后仍没有找到符合要求的序列,则为了避免重复赋值为0 break; } } } int maxx = -1; for (int i = 1; i <= n; i ++){ if (maxlen[i] > maxx) maxx = maxlen[i]; } int ans = 0; for (int i = 1; i <= n; i ++){ if (maxlen[i] == maxx) ans += maxnum[i] ; } printf("%d %d\n", maxx, ans); } return 0;}
[Maximum length and number of dropped subsequences] poj 1952