题意:在序列中去掉某个连续的子序列使得序列的最长上升子序列最长
题解:设l[i]为以i为结束的最长上升子序列的长度,r[i]为以i为开始的最长上升子序列的长度,那么dp[i]=r[j]+l[i],由于和普通的LIS类似,所以可以利用LIS的优化方法把该题的时间复杂的优化到O(nlogn)。方法仍是利用一个数组d[i]记录长度为 i 的连续递增序列的最后一个元素的最小值,显然该序列是单调递增的,所以可以通过二分查找直接得到l[j]的值,进而得到一个可行的长度ans, 然后更新数组d即可,更新的方法是如果以a[i]小于数组d中记录的与a[i]长度相同的序列的最后一个元素的值,那么把这个值改为a[i], 即 d[f[i]] = min(a[i], d[l[i]]); 最终ans的最大值即为答案。参考算法入门经典。
代码
#include <cstdio> #include <queue> #include <cstring> #include <iostream> #include <cstdlib> #include <algorithm> #include <vector> #include <map> #include <string> #include <set> #include <ctime> #include <cmath> #include <cctype> using namespace std; #define maxn 200000+10 #define LL long long int cas=1,T; int a[maxn]; int l[maxn]; int r[maxn]; int d[maxn]; const int INF = 1<<30; int main() { scanf("%d",&T); while (T--) { int n; scanf("%d",&n); for (int i = 1;i<=n;i++) scanf("%d",&a[i]); l[1]=1; for (int i = 2;i<=n;i++) { if (a[i] > a[i-1]) l[i]=l[i-1]+1; else l[i]=1; } r[n]=1; for (int i = n-1;i>0;i--) { if (a[i] < a[i+1]) r[i]=r[i+1]+1; else r[i]=1; } int ans = 0; for (int i = 0;i<=n;i++) d[i]=INF; for (int i = 1;i<=n;i++) { int len = (lower_bound(d+1,d+1+i,a[i]))-(d+1)+r[i]; ans = max(len,ans); d[l[i]]=min(a[i],d[l[i]]); } printf("%d\n",ans); } //freopen("in","r",stdin); //scanf("%d",&T); //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); return 0; }
题目
After the last war devastated your country, you - as the king of the land of Ardenia - decided it washigh time to improve the defense of your capital city. A part of your fortification is a line of magetowers, starting near the city and continuing to the northern woods. Your advisors determined that thequality of the defense depended only on one factor: the length of a longest contiguous tower sequenceof increasing heights. (They gave you a lengthy explanation, but the only thing you understood wasthat it had something to do with firing energy bolts at enemy forces).After some hard negotiations, it appeared that building new towers is out of question. Mages ofArdenia have agreed to demolish some of their towers, though. You may demolish arbitrary number oftowers, but the mages enforced one condition: these towers have to be consecutive.For example, if the heights of towers were, respectively, 5, 3, 4, 9, 2, 8, 6, 7, 1, then by demolishingtowers of heights 9, 2, and 8, the longest increasing sequence of consecutive towers is 3, 4, 6, 7.
Input
The input contains several test cases. The first line of the input contains a positive integer Z ≤ 25,denoting the number of test cases. Then Z test cases follow, each conforming to the format describedbelow.The input instance consists of two lines. The first one contains one positive integer n ≤ 2 · 105denoting the number of towers. The second line contains n positive integers not larger than 109separated by single spaces being the heights of the towers.
Output
For each test case, your program has to write an output conforming to the format described below.You should output one line containing the length of a longest increasing sequence of consecutivetowers, achievable by demolishing some consecutive towers or no tower at all.
Sample Input
2
9
5 3 4 9 2 8 6 7 1
7
1 2 3 10 4 5 6
Output
4
6