关于 O(n^2) 和 O(n log n) 的LIS
  • 板块学术版
  • 楼主TheSky233
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/4/4 21:34
  • 上次更新2023/10/28 04:35:23
查看原帖
关于 O(n^2) 和 O(n log n) 的LIS
501865
TheSky233楼主2022/4/4 21:34

rt.

在做 P3902 递增 时,起先用了朴素 dp 求 LIS,然后 WA 10pts(别在意为什么提交的人不是我,用小号交的).

O(n2)O(n^2) Code

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <array>
#include <map>
#include <bitset>
#include <vector>
#include <cstring>
#define int long long
using namespace std;

void read(int &x){
	x=0; int f=1; char ch=getchar();
	while(ch<'0' || ch>'9') f=(ch=='-')?-1:1,ch=getchar();
	while(ch>='0' && ch<='9') x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x=x*f;
}

const int N=2e3+5;

int n,m;
int a[N],b[N],f[N];

signed main(){
	read(n);
	for(int i=1;i<=n;i++) read(a[i]),b[i]=a[i]-i;
	for(int i=1;i<=n;i++) f[i]=1;
	
	for(int i=2;i<=n;i++)
		for(int j=1;j<i;j++)
			if(b[j]<=b[i])
				f[i]=max(f[i],f[j]+1);
	
	printf("%lld\n",n-f[n]);
	return 0;
}

然后痛定思痛,决定用 O(nlogn)O(n \log n) 的复杂度求 LIS,然后 AC 了。

O(nlogn)O(n \log n) Code

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <array>
#include <map>
#include <bitset>
#include <vector>
#include <cstring>
#define int long long
using namespace std;

void read(int &x){
	x=0; int f=1; char ch=getchar();
	while(ch<'0' || ch>'9') f=(ch=='-')?-1:1,ch=getchar();
	while(ch>='0' && ch<='9') x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x=x*f;
}

const int N=2e3+5;

int n,m,len;
int a[N],b[N],f[N];

signed main(){
	read(n);
	for(int i=1;i<=n;i++) read(a[i]),b[i]=a[i]-i;
	for(int i=1;i<=n;i++) f[i]=1;
	
	f[++len]=b[1];
	for(int i=2;i<=n;i++){
		if(b[i]>=f[len]) f[++len]=b[i];
		else *lower_bound(f+1,f+len+1,b[i])=b[i];
	}
	
	printf("%lld\n",n-len);
	return 0;
}

显然,中间 LIS 部分都是在求 b 数组的 LIS,为什么结果会不同?求教了。

2022/4/4 21:34
加载中...