标签:二分法 lower_bound 最长上升子序列 hdu
Description
Input
Output
Sample Input
4 64 2 6 3 1 5 102 3 4 5 6 7 8 9 10 1 88 7 6 5 4 3 2 1 95 8 9 2 3 1 7 4 6
Sample Output
3 9 1 4
我们有两种思路求可以参考shuoj上的D序列的题目。这里给出题目的题解链接::
主要是两种思路::(1)lower_bound(2)二分法,如果觉得代码不易理解可以点上面的链接
| 0 | 1 | 2 | 3 | 4 |
| 1 | 3 | |||
| 2 | 2 | |||
| 3 | 2 | 4 | ||
| 4 | 2 | 4 | 6 | |
| 5 | 2 | 4 | 5 | |
| 6 | 2 | 4 | 5 | 7 |
| 7 | 2 | 3 | 5 | 7 |
这里给出第二种方法代码::
#include <iostream>
#include<cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1e5 + 5;
int s[N];
int n,p,a[N];
int len;
int main()
{
cin>>n;
while(n--){
cin>>p;
memset(s,0,sizeof(s));
for(int i = 0;i<p;i++)cin>>a[i];
s[1] = a[0];len = 1;//长度从1开始
for(int i = 1;i<p;i++){
int t = a[i];
if(t>s[len])s[++len] = a[i];
else{
/*************/int l = 1,r = len,mid;//这里的二分法采用了左闭右闭的思路
<span style="white-space:pre"> </span>int ans = 0;
while(l<=r)
{
mid = (l+r)/2;
if(s[mid]<t)
{l = mid +1;ans = max(ans,mid);}//ans即为思路中的j,j必然为s数组中小于t的最大的数
else r = mid-1;
}
s[ans+1] = t;/******************/
}
}
//for(int i = 1;i<p;i++){cout<<s[i];}//有必要可以打开看看s中存的是什么值
cout<<len<<endl;
}
return 0;
}如果代码不易理解请点击链接,链接为::
第一种的代码只要将两个/**************/之间的代码换为
int p = lower_bound(s+1,s+len+1,t)-s; s[p] = t;就可以了。
3 9 1 4
3 9 1 4
| 0 | 1 | 2 | 3 | 4 |
| 1 | 3 | |||
| 2 | 2 | |||
| 3 | 2 | 4 | ||
| 4 | 2 | 4 | 6 | |
| 5 | 2 | 4 | 5 | |
| 6 | 2 | 4 | 5 | 7 |
| 7 | 2 | 3 | 5 | 7 |
版权声明:大家随意浏览。
HDU1950-Bridging signals-最长上升子序列
标签:二分法 lower_bound 最长上升子序列 hdu
原文地址:http://blog.csdn.net/sinat_30062549/article/details/47197073