标签:二分法 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