Uva-11456, hdu-3165 Irene is a train mechanic, she is also responsible for car scheduling. She liked to sort the carriage by weight from large to small, and put the heaviest carriage in front of the train. Unfortunately, it is not easy to arrange trains. You cannot pick up a carriage and put it elsewhere. It is not practical to insert a carriage into the middle of an existing train. A carriage can only be connected to the front or back of a train. The carriage arrives at the station in a predetermined order. When a carriage arrives, Irene can take it to the front or back of the train, or never take it. The longer the train, the better, but the trains must be arranged by weight. How long is the longest train Irene can take to give you the weight of the carriage in the order of arrival? This is a classic type of question. If you see this, you should think of LIS. Suppose that the first carriage chooses the I to put it in, then, the right side of the carriage must be smaller than the I, in order to keep the right side as long as possible, we need to place the order of the longest descending sequence from the I to the last in the sequence. To be placed on the left of I, the weight must be greater than that of I. Similarly, in order to keep the left direction as long as possible, I should be the first one (not to be replaced by others). If the simple method of enumerating the first carriage is used and the nlogn algorithm is used to calculate the longest increasing (decreasing) sequence, the complexity will reach n * logn and n will be up to 2000, the calculation amount reaches 2000*2000*11 = 4000 W +, obviously timeout. Therefore, you only need to calculate the longest ascending (subtraction) sequence in reverse order. For the I-th sequence, when it is inserted into the LIS sequence, you can get the longest increasing (decreasing) Starting with it) the length of the sequence, which is equal to the number of the first insertion position in the LIS sequence, is the length of its longest incremental sequence. It may not be clear and the code is easy to understand. Note: When I find the longest descending sequence, I convert each number into a negative number, which turns into the longest ascending sequence, which is more convenient to do. Code
/**===================================================== * This is a solution for ACM/ICPC problem * * @source : uva-11456 Trainsorting * @description : dp, LIS * @author : shuangde * @blog : blog.csdn.net/shuangde800 * @email : zengshuangde@gmail.com * Copyright (C) 2013/09/06 22:09 All rights reserved. *======================================================*/#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>using namespace std;const int MAXN = 2010;int n;int arr[MAXN];int main(){ int nCase; scanf("%d", &nCase); while (nCase--) { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); vector<int>vt1, vt2; vector<int>::iterator iter; int ans = 0; for (int i = n - 1; i >= 0; --i) { int len1, len2; iter = lower_bound(vt1.begin(), vt1.end(), arr[i]); if (iter == vt1.end()) { vt1.push_back(arr[i]); len1 = vt1.size(); } else{ *iter = arr[i]; len1 = iter - vt1.begin() + 1; } iter = lower_bound(vt2.begin(), vt2.end(), -arr[i]); if (iter == vt2.end()) { vt2.push_back(-arr[i]); len2 = vt2.size(); } else { *iter = -arr[i]; len2 = iter - vt2.begin() + 1; } ans = max(ans, len1 + len2 - 1); } printf("%d\n", ans); } return 0;}