最长上升子序列问题

最长上升子序列

1.O(n^{2})算法:dp[i]代表以ai元素为结尾的最长上升子序列长度。每次遍历1~i-1,如果ai>aj,dp[i]=max(dp[i],dp[j]+1)。

2.O(nlogn)算法:贪心思想:

        1.用一个b数组记录序列(这个序列不是正确的,只是长度和答案一样)

        2. 遍历a数组,如果ai>b的末尾元素,直接添加进b数组。若小于,用ai替换第一个大于等于ai的元素(注意是大于等于)

        该算法的正确性博主能力有限,不会证明。

例题:

洛谷B3637

1.动态规划法:

#include
#define ll long long
#define N 5005
using namespace std;
ll arr[N],dp[N],n,ans=0;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
	cin>>arr[i],dp[i]=1;
for(int i=1;i<=n;i++)
	for(int j=1;j

2.贪心二分法:

#include
#define ll long long
#define N 5005
using namespace std;
ll a,n;
vectorans;
int main()
{
cin>>n;
cin>>a;
ans.push_back(a);
for(int i=2;i<=n;i++){
	cin>>a;
	if(a>*(ans.end()-1)) ans.push_back(a);
	else *lower_bound(ans.begin(),ans.end(),a)=a;
}	
cout<

洛谷P1439

虽说这个题的名字叫最长公共子序列,其实是考最长上升子序列问题。利用全排列的性质,将a的排列作为基准,得到b中元素的排名,求b中的最长上升子序列即为答案。

#include
#define N 100005
using namespace std;
int n,v[N],a;
vectorb;
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
	cin>>a;
	v[a]=i;
}		
for(int i=1;i<=n;i++){
	cin>>a;
	a=v[a];
	if(b.empty()) b.push_back(a);
	else{
		if(a>*(b.end()-1)) b.push_back(a);
		else *lower_bound(b.begin(),b.end(),a)=a;
	}
}
cout<

你可能感兴趣的:(最长上升子序列问题)