您的位置:首页 > 其它

最长不下降序列nlogn算法

2013-05-05 19:55 176 查看
O(nlogn)的算法关键是它建立了一个数组temp[],temp[i]表示长度为i的不下降序列中结尾元素的最小值,用top表示数组目前的长度,算法完成后top的值即为最长不下降子序列的长度。设当前的以求出的长度为top,则判断num[i]和temp[top]:1.如果num[i]>=temp[top],即num[i]大于长度为top的序列中的最后一个元素,这样就可以使序列的长度增加1,即top++,然后现在的temp[top]=num[i];2.如果num[i]<temp[top],那么就在temp[1]...temp[top]中找到最大的j,使得temp[j]<num[i],然后因为temp[j]<num[i],所以num[i]大于长度为j的序列的最后一个元素,那么就可以更新长度为j+1的序列的最后一个元素,即temp[j+1]=num[i]。
#include <iostream>
#define SIZE 1001

using namespace std;

int main()
{
int i, j, n, top, temp;
int stack[SIZE];
cin >> n;

top = 0;
/* 第一个元素可能为0 */
stack[0] = -1;
for (i = 0; i < n; i++)
{
cin >> temp;
/* 比栈顶元素大数就入栈 */
if (temp > stack[top])
{
stack[++top] = temp;
}
else
{
int low = 1, high = top;
int mid;
/* 二分检索栈中>=temp的第一个数的下标 */
while(low <= high)
{
mid = (low + high) / 2;
if (temp > stack[mid])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
/* 用temp替换 */
stack[low] = temp;       //这个下标的前一个数即为小于temp的最大的数
}
}

/* 最长序列数就是栈的大小 */
cout << top << endl;

//system("pause");
return 0;
}
用lower_bound函数实现:
#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>#include <queue>#include <cmath>#include <vector>#include <cstdlib>using namespace std;int main(){int stack[1005];int n,top=0,temp;cin>>n;stack[0]=-1;for(int i=0;i<n;i++){cin>>temp;if(temp>=stack[top])stack[++top]=temp;else{int loc=lower_bound(stack,stack+top,temp)-stack;  //返回第一个>=temp的数的下标,则这个数的前一个数就是<temp的下标最大的数stack[loc]=temp;}}cout<<top<<endl;return 0;}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: