// 编程之美之最长递增子序列.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <algorithm>
using namespace std;
#define N 8
#define MAXN 1003
int A[MAXN];
int MaxV[MAXN];
// 动态规划算法O(nlogn)
/*int _tmain(int argc, _TCHAR* argv[])
{
int n, i, j, k;
cin >> n;
for (i=1; i<=n; i++)
cin >> A[i];
MaxV[1] = A[1];
int nmaxv = 1; // 目前找到的最长递增子序列的长度
// 有n个阶段,每个阶段有1个状态
for (i=2; i<=n; i++)
{
// 每个状态有nmaxv种决策,以得出以元素i结尾的最长递归子序列的长度
int u = 1, v = nmaxv;
while (u<=v)
{
int mid = (u+v)>>1;
if (MaxV[mid] < A[i])
u = mid+1;
else
v = mid-1;
}
// 每个元素都会对数组MaxV中的某个元素产生影响
// 使用二分搜索确定其在第v+1个位置
nmaxv = max(nmaxv, v+1);
MaxV[v+1] = A[i];
}
cout << nmaxv;
system("pause");
return 0;
}*/
int _tmain(int argc, _TCHAR* argv[])
{
int n, i, j, k;
int *arr = new int[N];
int *lengest_min = new int[N+1];//lengest_min[i]表示长度为i的所有子序列中,满足arr[i]最小的子序列,及最后一个值是最小的子序列,lengest_min[i]就是最小子序列的最后的值(最大值)
for (i=0; i<N; i++)
{
cin >> arr[i];
//cout<<" next "<<endl;
}
//cout<<" start "<<endl;
lengest_min[1]=arr[0];//第一个元素的最小子序列长度为一,最后一个元素是arr【0】
int minmax=1;
for(int i=1;i<=N;i++)
{
int low=1,mid,high;
high = minmax;//minmax 是lengest_min[]数组的最大值,
//寻找arr[i]的位置,寻找那些lengest_min[j]的值小于arr[i]的点,若lengest_min[j]的值小于arr[i],说明该子序列可以更长一点,该子序列的最后的值也应更大一点
// 即在lengest_min[] 的数组里找小于arr【i】的元素,因为lengest_min[]有序(迭代的过程要维持有序),所以用二分查找
while(low<=high)
{
mid=(low+high)/2;
if(lengest_min[mid]<arr[i])
low=mid+1;
else high=mid-1;
}// 结束时确实插入位置在high+1处
//cout<<"high +1 is "<<high+1<<endl;
if(minmax<high+1) minmax=high+1;
lengest_min[high+1]=arr[i];//更新lengest-min【】
//cout<<" lengestmin is "<<lengest_min[high+1]<<endl;
}
cout<<" is "<<minmax;
system("pause");
return 0;
}编程之美之最长递增子序列实现
最新推荐文章于 2023-11-01 12:49:25 发布
本文介绍了一种求解最长递增子序列问题的有效算法,采用动态规划结合二分搜索的方法,实现时间复杂度为O(nlogn)。通过实例展示了如何利用数组记录递增子序列的状态,并逐步迭代优化子序列的长度。
2306

被折叠的 条评论
为什么被折叠?



