题意:给你一个序列,问你删除掉连续的一段,使得剩下的序列的最长上升字串最大,问你这个最大值。

解题思路:分段dp,  dp[i][0] ,dp[i][1]   , 0表示前面没有切过,只能从前一个数的0状态得到,1状态表示前面已经切过了,能从前一个的1状态得到,也能从 在他前面的比他值小的dp[j][0](j < i && a[j] < a[i])的最大值得到,这里用线段树维护就行了。

解题代码:

  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\n",dp[i][0],dp[i][1],mx);
106          } 
107          printf("%d\n",ans+1);
108     }
109 return 0;
110 }
View Code

 

posted on 2015-03-29 09:07  dark_dream  阅读(322)  评论(4编辑  收藏  举报