D. Trainsorting (100)
Time Limit: 1s Memory Limit: 256MB
Erin is an engineer. She drives trains. She also arranges the cars within each train. She prefers to put the cars in decreasing order of weight, with the heaviest car at the front of the train.
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?
Input Data
The first line contains an integer , 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.
Output Data
Output a single integer giving the number of cars in the longest train that can be made with the given restrictions.
Sample Input
3
1
2
3
Sample Output
3
思路:将此题看成最长上升子序列和最长下降子序列的结合。我们首先维护数组的最长下降子序列所得到的最长长度dp_i,从小到大的ep_i,然后计算答案的时候,我们分别考虑下面三种情况,要么答案是max(dp[i],ep[i]),要么是,这个数作为最长下降子序列的开头,若后面有比他小的,就尝试“拼接”,这个数作为最长上升子序列的末尾时也同理。
#include <bits/stdc++.h>
using namespace std;
const int N=2010;
int dp[N];
int ep[N];
int a[N];
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
fill(dp, dp + 1 + n, 1);
fill(ep, ep + 1 + n, 1);
for(int i = n; i >= 1; --i) {
for (int j = n; j > i; --j) {
if (a[j] > a[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
if(a[j] < a[i]) {
ep[i] = max(ep[i], ep[j] + 1);
}
}
}
int ans = 0;
for(int i = 1;i <= n; i++) {
ans = max(ans, max(dp[i], ep[i]));
for(int j = i + 1;j <= n; j++) {
if(a[i] < a[j]) {
ans = max(ans, dp[j] + ep[i]);
}
else if(a[i] > a[j]) {
ans = max(ans, dp[i] + ep[j]);
}
}
}
cout << ans << '\n';
return 0;
}