题意:给你一个序列,问你删除掉连续的一段,使得剩下的序列的最长上升字串最大,问你这个最大值。
解题思路:分段dp, dp[i][0] ,dp[i][1] , 0表示前面没有切过,只能从前一个数的0状态得到,1状态表示前面已经切过了,能从前一个的1状态得到,也能从 在他前面的比他值小的dp[j][0](j < i && a[j] < a[i])的最大值得到,这里用线段树维护就行了。
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // File Name: e.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月28日 星期六 14时37分24秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 #define maxn 10005 26 using namespace std; 27 int n ; 28 int dp[maxn][2]; 29 int a[maxn]; 30 struct node{ 31 int l ,r , m , v; 32 }tree[maxn*4]; 33 int L(int x) 34 { 35 return 2 * x; 36 } 37 int R(int x) 38 { 39 return 2 *x + 1; 40 } 41 void push_up(int c) 42 { 43 tree[c].v = max(tree[L(c)].v,tree[R(c)].v); 44 } 45 void build(int c ,int l , int r) 46 { 47 tree[c].l = l; 48 tree[c].r = r ; 49 tree[c].m = (l + r)/2; 50 tree[c].v = -1; 51 if(tree[c].l ==tree[c].r) 52 { 53 return; 54 } 55 build(L(c),l,tree[c].m); 56 build(R(c),tree[c].m+1,r); 57 } 58 int mx = 0 ; 59 void find(int c,int l , int r) 60 { 61 if(tree[c].l >= l && r >= tree[c].r) 62 { 63 mx = max(tree[c].v,mx); 64 return; 65 } 66 if(l <= tree[c].m) 67 find(L(c),l,r); 68 if(r > tree[c].m) 69 find(R(c),l,r); 70 } 71 void update(int c, int p , int v) 72 { 73 if(tree[c].l == tree[c].r) 74 { 75 tree[c].v = max(tree[c].v,v); 76 return; 77 } 78 if(p <= tree[c].m) 79 update(L(c),p,v); 80 else update(R(c),p,v); 81 push_up(c); 82 } 83 int main(){ 84 while(scanf("%d",&n) != EOF) 85 { 86 build(1,1,10000); 87 a[0] = 0 ; 88 memset(dp,0,sizeof(dp)); 89 int ans = 0; 90 for(int i = 1;i <= n;i ++) 91 { 92 scanf("%d",&a[i]); 93 if(a[i] > a[i-1] && i!= 1) 94 { 95 dp[i][0] = dp[i-1][0] + 1; 96 ans = max(dp[i][0],ans); 97 dp[i][1] = dp[i-1][1] + 1; 98 } 99 update(1,a[i],dp[i][0]); 100 mx = -1; 101 if(a[i] != 1) 102 find(1,1,a[i]-1); 103 dp[i][1] = max(dp[i][1] ,mx + 1); 104 ans = max(dp[i][1],ans); 105 //printf("%d %d %d ",dp[i][0],dp[i][1],mx); 106 } 107 printf("%d ",ans+1); 108 } 109 return 0; 110 }