大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn
航线问题
题目描述
Description
随着国际贸易和中美关系的发展,在美国西海岸的许多港口和中国沿海港口都建立了一对一的联系,中美政府计划开通一些航线来刺激经济。航线一旦开通,将会有源源不断的货物通过航线在两个港口之间运输,因此要保证航线不能相交。
由于航线都是横跨太平洋的,所以可以把中国沿海港口和美国西海岸港口看成两条直线。 如下图所示,连线则表示港口之间有联系,在同一位置只有一个港口,且一个港口有且只有一个对岸的联系港口。
为了满足经济发展的要求,现在请你求出最多能开通的航线数目。
输入描述
Input
第一行一个整数T表示有T组测试数据:
每组测试数据第一行有一个整数N(1<=N<=100,000)
接下来N行,每行两个整数a,b(0<=a,b<=2,000,000,000)表示两岸坐标分别为a和b的两个港口有联系。
输出描述
Output
每组数据输出一个整数,表示最多能开通的航线数。
样本输入
Input example
1
4
23 18
45 7
3 6
21 8
样本输出
Output example
3
分析
解题思路:
- 先将全部的a,b城市按照a的大小从小到大排序.
- 做动态规划题目步骤:
1. 找转移状态: dp[i]: 表示当前i个城市的最大升序的长度.
2. 状态转移方程:
当dp[i] > dp[j] (i >= j) dp[i] = max(dp[i],dp[j]+1)
;
- 动态规划。时间复杂度为 O ( n 2 ) O(n^2) O(n2),题目限定数据较大,超时
/*
* @Author: motongxue
* @Date: 2020-08-01 10:34:08
* @LastEditors: motongxue
* @LastEditTime: 2020-08-01 10:43:05
* @Blog: https://motongxue.cn
* @Description: file content
*/
import java.util.Arrays;
import java.util.Scanner;
class Node implements Comparable<Node>{
int a, b;
Node(int a,int b){
this.a = a;
this.b = b;
}
@Override
public int compareTo(Node o) {
return this.a-o.a;
}
}
public class Main {
static int a,b,n,t;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
t = sc.nextInt();
while(t-->0){
n = sc.nextInt();
Node[] nodes = new Node[n];
int[] dp = new int[n];
for(int i=0;i<n;i++){
a = sc.nextInt();
b = sc.nextInt();
dp[i] = 1;
Node node = new Node(a,b);
nodes[i] = node;
}
int res=0;
Arrays.sort(nodes);
for(int i=0;i<n;i++){
for(int j=0;j<=i;j++){
if(nodes[i].b>nodes[j].b){
dp[i] = Math.max(dp[i],dp[j]+1);
}
}
res = Math.max(dp[i],res);
}
System.out.println(res);
}
}
}
- 贪心加二分。时间复杂度为 O ( n l o g n ) O(nlog_n) O(nlogn),AC
/*
* @Author: motongxue
* @Date: 2020-08-01 10:34:08
* @LastEditors: motongxue
* @LastEditTime: 2020-08-01 10:54:05
* @Blog: https://motongxue.cn
* @Description: file content
*/
import java.util.Arrays;
import java.util.Scanner;
class Node implements Comparable<Node>{
int a, b;
Node(int a,int b){
this.a = a;
this.b = b;
}
@Override
public int compareTo(Node o) {
return this.a-o.a;
}
}
public class Main {
static int a,b,n,t;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
t = sc.nextInt();
while(t-->0){
n = sc.nextInt();
Node[] nodes = new Node[n];
int[] dp = new int[n+1];
for(int i=0;i<n;i++){
a = sc.nextInt();
b = sc.nextInt();
Node node = new Node(a,b);
nodes[i] = node;
}
Arrays.sort(nodes);
dp[1] = nodes[0].b;
int index = 1;
for(int i=1;i<n;i++){
if(nodes[i].b>dp[index]){
dp[++index] = nodes[i].b;
}else{
int tempIndex = BinarySearch(dp, index, nodes[i].b);
dp[tempIndex] = nodes[i].b;
}
}
System.out.println(index);
}
}
// 二分查找变体 找到第一个大于n的位置index
private static int BinarySearch(int[] dp, int len, int n) {
int left = 1;
int right = len;
while (right > left) {
int mid = (left + right) / 2;
if (dp[mid] == n) {
return mid;
} else if (dp[mid] < n) {
left = mid + 1;
} else {
right = mid;//注意这里不能为right = mid -1;
}
}
return right;
}
}
2020年8月1日更
大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn