[每日一题]: 最长上升子序列 AND 最长不上升子序列

关于知识点的讲解:

最长上升子序列讲解及二分优化

例题:

最长上升子序列题目链接:

Bridging signals

普通版本:

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 1005;

int dp[maxn];

int a[maxn];

int n;

int main(void) {
	scanf("%d",&n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d",&a[i]);
	}
	int ans = 0;
	for(int i = 1;  i <= n; i ++) {
		dp[i] = 1;
		for(int j = 1; j < i; j ++) {
			if(a[i] > a[j]) {
				dp[i] = max(dp[j] + 1,dp[i]);
			}
		}
	}
	for(int i = 1; i <= n; i ++) {
		ans = max(ans,dp[i]);
	}
	cout << ans << endl;
	return 0;
} 

二分优化:

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 10;

int dp[maxn],a[maxn];

int low[maxn];

int n,cnt = 1;

int serch(int x) {
	int l = 1, r = cnt;
	while(l < r) {
		int mid = l + r >> 1;
		if(low[mid] >= x) r = mid;
		else l = mid + 1;
	}
	return r;
}

int main(void) {
	scanf("%d",&n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d",&a[i]);
	}
	memset(low,0x3f,sizeof(low));
	low[1] = a[1];
	for(int i = 1; i <= n; i ++) {
		if(a[i] > low[cnt]) low[ ++ cnt] = a[i];
		else {
			int pos = serch(a[i]);
			low[pos] = a[i];
		}
	}
	printf("%d\n",cnt);
	return 0;
}

最长不上升子序列例题:

小明爱拦截

侃侃:

  这个题是在最长上升子序列版本上的改动,如果最长上升子序列搞懂了,
  这个应该不难。

普通版:

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 10;

int dp[maxn],a[maxn];

int n;

int main(void) {
	scanf("%d",&n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d",&a[i]);
	}	
	for(int i = 1; i <= n; i ++) {
		dp[i] = 1;
		for(int j = 1; j < i; j ++) {
			if(a[j] >= a[i]) {
				dp[i] = max(dp[i],dp[j] + 1);
			}
		}
	}
	int res = 0;
	for(int i = 1; i <= n; i ++) {
		res = max(res,dp[i]);
	}
	cout << res << endl;
	return 0;
} 

二分优化:

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 10;

int dp[maxn],a[maxn];

int low[maxn];

int n,cnt = 1;

int serch(int x) {
	int l = 1,r = cnt;
	while(l < r) {
		int mid = (l + r )>> 1;
		if(low[mid] < x) r = mid;
		else l = mid + 1;
	}
	return r;
}

int main(void) {
	scanf("%d",&n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d",&a[i]);
	}
	memset(low,0x3f,sizeof(low));
	low[1] = a[1];
	for(int i = 2; i <= n; i ++) {
		if(a[i] <= low[cnt]) {
			low[++ cnt] = a[i];
		} else {
			int pos = serch(a[i]);
			low[pos] = a[i];
		}
	}
	printf("%d\n",cnt);
	return 0;
}
posted @ 2020-05-06 20:26  IceSwords  阅读(240)  评论(0编辑  收藏  举报