Unfortunately, sorting train cars is not easy. One cannot simply pick up a car and place it somewhere else. It is impractical to insert a car within an existing train. A car may only be added to the beginning and end of the train.
Cars arrive at the train station in a predetermined order. When each car arrives, Erin can add it to the beginning or end of her train, or refuse to add it at all. The resulting train should be as long as possible, but the cars within it must be ordered by weight.
Given the weights of the cars in the order in which they arrive, what is the longest train that Erin can make?
The first line contains an integer 0 <= n <= 2000, the number of cars. Each of the following n lines contains a non-negative integer giving the weight of a car. No two cars have the same weight.
1 3 1 2 3
3
题意:
一些车厢,一辆辆从头到尾开进站,进站的时候可以选择接在头或者尾,或者放弃这节,但是必须保证车厢从头到尾是从大到小的,问最长能接几节。
思路:
LIS,对于每一个位置,需要找出从这个位置往后,比这个数字大的最长上升子序列和比这个数字小的最长上升子序列,dp[i]表示到i个位置以i为结尾的LIS最长是多少,然后逆序去DP即可。
代码:
#include <stdio.h> #include <string.h> #define max(a,b) ((a)>(b)?(a):(b)) const int N = 2005; int t, n, train[N], dp1[N], dp2[N]; int solve() { int ans = 0; for (int i = n; i >= 1; i--) { dp1[i] = dp2[i] = 1; for (int j = n; j > i; j--) { if (train[i] > train[j]) dp1[i] = max(dp1[i], dp1[j] + 1); else dp2[i] = max(dp2[i], dp2[j] + 1); } ans = max(ans, dp1[i] + dp2[i] - 1); } return ans; } int main() { scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 1; i <= n ; i++) scanf("%d", &train[i]); printf("%d\n", solve()); } return 0; }