轮船问题

原题链接

描述

某国家被一条河划分为南北两部分,在南岸和北岸总共有nn对城市,每一城市在对岸都有唯一的友好城市,任何两个城市都没有相同的友好城市。每一对友好城市都希望有一条航线来往,于是他们向政 府提出了申请。由于河终年有雾,政 府决定开通的航线互不交叉(如果两条航线交叉,将有很大机会撞船)。兴建哪些航线以使在安全条件下有最多航线可以被开通。

输入

包括了若干组数据,每组数据格式如下:

第一行两个由空格分隔的整数x,y(10x10000,10y100)x,y(10≤x≤10000,10≤y≤100)。x表示河的长度而y表示宽。

第二行是一个整数n(1n5000)n(1≤n≤5000),表示分布在河两岸的城市对数。接下来的n行每行有两个由空格分隔的正整数C,D(C,Dx)C,D(C,D≤x),描述每一对友好城市与河起点的距离,CC表示北岸城市的距离而DD表示南岸城市的距离。在河的同一边,任何两个城市的位置都是不同的。

输出

输出每一组数据在安全条件下能够开通的最大航线数目。

输入样例 1

30 4

5

4 5

2 4

5 2

1 3

3 1

输出样例 1

3

动态规划

这道题求选出最大的航线数目,结合题意,很明显就是动态规划嘛。

首先要知道,如何判断两条航线交叉与否,不难发现有两种情况:

(假设a[i]是这边,b[i]就是另一边)

  • a[i]>b[i]

  • a[i]<b[i]

当a[i]>b[i]时,如果a[j]<a[i] && b[j]>b[i] 就是重叠。

当a[i]<b[i]时,如果a[j]>a[i] && b[j]<a[i] 就是重叠。

一看,只要保证其中a的顺序,那不就是求b的最长上升子序列吗?

直接排序,然后求最长上升子序列。

代码

#include<bits/stdc++.h>
using namespace std;
struct Node {
	int l,r;
}a[11111];
bool cmp(Node x ,Node y) {
	return x.l<y.l;
}
int dp[1111111];
int x,y,n;
int main() {
	cin>>x>>y>>n;
	for(int i=1;i<=n;i++) {
		cin>>a[i].l>>a[i].r;
		dp[i]=1;
	}
	sort(a+1,a+n+1,cmp);
	int ans=0;
	for(int i=1;i<=n;i++) {
		for(int j=1;j<i;j++) {
			if(a[i].r>a[j].r)
				dp[i]=max(dp[i],dp[j]+1);
		}
	}
	for(int i=1;i<=n;i++) {
		ans=max(ans,dp[i]);
	}
	cout<<ans;
	return 0;
}

其他

其实还有一种方法,就是用数组a的值表示y的位置,用下标表示x的位置。

遍历1~x,对a数组求最长上升子序列,类似于桶排序吧。

热心同学的代码

#include<bits/stdc++.h>
using namespace std;
int f[60100],x,y,n,p;
int dp[60100],ans;
int main(){
	memset(f,-1,sizeof(f));
	cin>>x>>y>>n;
	for(int i=1;i<=n;++i){
		cin>>p;
		cin>>f[p];
	}
	for(int i=1;i<=x;i++)dp[i]=1;
	for(int i=1;i<=x;i++){
		if(f[i]!=-1){
			for(int j=1;j<i;j++){
				if(f[i]>f[j])dp[f[i]]=max(dp[f[i]],dp[f[j]]+1);
			}
			ans=max(dp[f[i]],ans);
		}
	}
	cout<<ans;
	return 0;
}

时间复杂度

在时间复杂度上,最优情况下第二种方法≈第一种方法=O(N2)O(N^2)。(也就是1~x都有船)

最坏情况下,第二种方法是O(N2)O(N^2)以上,比第一种方法慢一些,但是省了一点空间。

本文作者:cjrqwq

本文链接:https://www.cnblogs.com/yfzqwq/p/18492852

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   cjrqwq  阅读(15)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
展开
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.