友好城市(dp算法)

友好城市

题意:每一个桥有两个点,求最多所有不相交的桥的数。

这个题也是最长上升子序列的应用题,我们只需要对一边的端点排序,再多另一边的端点求最长上升子序列即可,因为一边端点有序,另一边端点求最长上升子序列就可以保证这些桥不相交。自行脑补。

这题需要用到最长上升子序列的优化,朴素只能得部分分

朴素版代码

#include
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=5e3+7;
PII a[N];
int dp[N];
int main(){
	int n,res=0;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y;
	}
	sort(a+1,a+1+n);
	for(int i=1;i<=n;i++){
		dp[i]=1;
		for(int j=1;j<i;j++){
			if(a[i].y>a[j].y){
				dp[i]=max(dp[i],dp[j]+1);
			}
		}
		res=max(res,dp[i]);
	}
	cout<<res<<endl;
	return 0;
}

优化版代码

当前的数如果大于up数组里的数就直接添加,否则就可以在up数组中替换一个数使得后面的答案更优

#include
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=2e5+7;
PII a[N];
int dp[N];
int up[N],u;
int main(){
	int n,res=0;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y;
	}
	sort(a+1,a+1+n);
	up[u]=a[1].y;
	for(int i=2;i<=n;i++){
		if(a[i].y>up[u])up[++u]=a[i].y;
		else up[lower_bound(up,up+u,a[i].y)-up]=a[i].y;
	}
	cout<<u+1<<endl;//加一是因为下标从0开始
	return 0;
}

你可能感兴趣的:(算法,dp算法)