题意:给你一个序列,问你删除掉连续的一段,使得剩下的序列的最长上升字串最大,问你这个最大值。
解题思路:分段dp, dp[i][0] ,dp[i][1] , 0表示前面没有切过,只能从前一个数的0状态得到,1状态表示前面已经切过了,能从前一个的1状态得到,也能从 在他前面的比他值小的dp[j][0](j < i && a[j] < a[i])的最大值得到,这里用线段树维护就行了。
解题代码:
1 // File Name: b.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月28日 星期六 13时26分39秒 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 26 using namespace std; 27 int n , x, y , c1,c2; 28 int tsum; 29 double ans ; 30 double dis(double x1,double y1,double x2,double y2) 31 { 32 return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); 33 } 34 void fen(double low ,double high) 35 { 36 double mid1 = low + (high - low) *1/3; 37 double mid2 = low + (high - low) *2/3; 38 double ansmid1 =dis(0,0,tsum,mid1)*c2 + dis(tsum,mid1,x,y)*c1; 39 double ansmid2 =dis(0,0,tsum,mid2)*c2 + dis(tsum,mid2,x,y)*c1; 40 if(fabs(ansmid2-ansmid1) < 1e-6) 41 { 42 ans = ansmid2; 43 return; 44 } 45 if(ansmid1 < ansmid2) 46 fen(low,mid2); 47 else fen(mid1,high); 48 } 49 int main(){ 50 while(scanf("%d %d %d %d %d",&n,&x,&y,&c1,&c2) != EOF) 51 { 52 int tx, ty ; 53 tsum = 0 ; 54 for(int i = 1;i<= n ;i++) 55 { 56 scanf("%d %d",&tx,&ty); 57 tsum += ty; 58 } 59 fen(0,y); 60 printf("%.2f\n",ans); 61 } 62 return 0; 63 }
湖南多校对抗赛(2015.03.28) E Longest Increasing Subsequence Again
原文:http://www.cnblogs.com/zyue/p/4375237.html