最长上升子序列
来源:互联网 发布:知客文化传播 培训 编辑:程序博客网 时间:2024/06/06 00:30
今天又把最长上升子序列学了一遍,
有两种时间复杂度不同的算法来解决这个问题:
现在稍微解释一下:
(1)O(n^n)
给你一个序列:1 3 2 4 8 7 a[i=1...i=6]
我们用dp[i]表示 从第1个数开始到第i个数结束的最长上升子序列的长度。经典dp;
#include <iostream>
using namespace std;
int a[110];
int dp[110];
int main()
{
int t;
int n;
cin>>t;
while(t--)
{
cin>>n;
memset(dp,1,sizeof(dp));
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
if(a[j]<a[i])
dp[i]=max(dp[i],dp[j]+1);
}
int maxn=-999;
for(int i=1;i<=n;i++)
{
if(dp[i]>maxn)maxn=dp[i];
}
cout<<maxn<<endl;
}
return 0;
}
using namespace std;
int a[110];
int dp[110];
int main()
{
int t;
int n;
cin>>t;
while(t--)
{
cin>>n;
memset(dp,1,sizeof(dp));
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
if(a[j]<a[i])
dp[i]=max(dp[i],dp[j]+1);
}
int maxn=-999;
for(int i=1;i<=n;i++)
{
if(dp[i]>maxn)maxn=dp[i];
}
cout<<maxn<<endl;
}
return 0;
}
(2)O(n*logn)
从第一种方法中,我们已经知道了dp[i]表示的是到第i个数结束的最长上升子序列的长度。那么假设现在有 :dp[x]==dp[y]&&a[x]<a[y] 那最优选法是将a[x]进入序列还是让a[y]
进入序列呢??? 显然让a[x]进入序列是最优的,因为a[x]<a[y],那么a[x]相对于a[y]更有潜力,因为时间关系,先附上代码:
#include <iostream>
using namespace std;
int a[110],d[110],
int BinSearch(int key,int *d,int low,int high)
{
while(low<=hign)
{
int mid=low+(high-low)/2;
if(d[mid]<key&&key<=d[mid+1])
return mid;
else if(d[mid]<key)
low=mid+1;
else
high=mid-1;
}
}
int lis(int *a,int n,int *d)
{
int i,j,len;
d[1]=a[1];
len=1;
for(i=2;i<=n;i++)
{
if(d[i-1]<a[i])
j=++len;
else
j=BinSearch(a[i],d,1,len);
d[j]=a[i];
}
return len;
}
int main()
{
int t;
int n;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
cout<<lis(a,n,d)<<endl;
}
return 0;
}
using namespace std;
int a[110],d[110],
int BinSearch(int key,int *d,int low,int high)
{
while(low<=hign)
{
int mid=low+(high-low)/2;
if(d[mid]<key&&key<=d[mid+1])
return mid;
else if(d[mid]<key)
low=mid+1;
else
high=mid-1;
}
}
int lis(int *a,int n,int *d)
{
int i,j,len;
d[1]=a[1];
len=1;
for(i=2;i<=n;i++)
{
if(d[i-1]<a[i])
j=++len;
else
j=BinSearch(a[i],d,1,len);
d[j]=a[i];
}
return len;
}
int main()
{
int t;
int n;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
cout<<lis(a,n,d)<<endl;
}
return 0;
}
0 0
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- C语言中如何使用宏 包括单双井号 可变参数
- 算法实验二:微软面试题——关于整数组最小差值的问题。
- [php扩展开发和嵌入式]第17章-php源代码的配置和链接
- wait与notify实现多线程的协调通信
- 老调重弹:JDBC系列 之 <驱动加载原理全面解析>
- 最长上升子序列
- mtk LCD 驱动过程详解
- NetMap中查看Esri shape文件
- UNIX中的标准IO库
- mac下给手机安装apk包
- 微乐的六维裂变
- poj-1151-Atlantis-线段树求面积并
- 第2次实验——算法基本功 与 综合思考
- SQL Server 全文索引查询T-SQL学习笔记之二(Full-text index)