区间选点问题-贪心策略
Posted nuist__NJUPT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间选点问题-贪心策略相关的知识,希望对你有一定的参考价值。
区间选点问题
给定n个整数闭区间,以及他们需要命中点的数目,设计程序求出最少需要多少个点
输入值
第一行间隔数n(1 <= n <= 50000)。以下n行每行三个整数之间用空格隔,ai、bi、ci分别为区间两端点,需要命中的点数。因此0 <= ai <= bi <= 50000和1 <= ci <= bi-ai + 1。
输出量
最少需要的点数
样例输入:
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
样例输出:
6
- 算法思想:将所有的三个点封装成一个数组,并对每个区间按照结束时间升序排序,根据贪心策略,先判断所需选择的点数,然后从区间的右侧开始选点,如果没被选过,则选择,否则跳过,直到每个区间都选点完成,最终统计区间中被选择的点的个数即可。
import java.util.Arrays;
import java.util.Scanner;
public class IntervalPointSelect {
public static class Interval implements Comparable<Interval>{
int s, t, c ; //三个数字分别为区间的两个端点以及需要命中的点数
public Interval(int s, int t, int c){
this.s = s ;
this.t = t ;
this.c = c ;
}
@Override
public int compareTo(Interval other) { //按照结束时间最早的排序
int x = this.t - other.t ;
if(x == 0){
return this.s - other.s ;
}else{
return this.t - other.t ;
}
}
}
public static int sum(int [] axis, int s, int t){
int count = 0 ;
for(int i=s; i<=t; i++){
if(axis[i] == 1){
count ++ ;
}
}
return count ;
}
public static void main(String[] args){
Scanner input = new Scanner(System.in) ;
int n = input.nextInt() ;
Interval [] intervals = new Interval [n] ;
for(int i=0; i<n; i++){
intervals[i] = new Interval(input.nextInt(), input.nextInt(), input.nextInt()) ;
}
Arrays.sort(intervals) ; //按区间右端点进行排序
int max = intervals[n-1].t ; //右端的最大值
int [] axis = new int [max+1] ; //标记数轴上点是否被选中
for(int i=0; i<n; i++){
int s = intervals[i].s ; //起点
int t = intervals[i].t ; //终点
int count = sum(axis, s, t) ; //计算这个区间已经选点的数量
//如果不够的话,从端点右侧开始标记,遇到标记过的就跳过
intervals[i].c -= count ; //需要新增的点数
while(intervals[i].c > 0){
if(axis[t] == 0){ //从区间终点开始选点
axis[t] = 1 ;
intervals[i].c -- ;
t -- ;
}else{
t -- ;
}
}
}
System.out.println(sum(axis, 0, axis.length-1)) ;
}
}
以上是关于区间选点问题-贪心策略的主要内容,如果未能解决你的问题,请参考以下文章
uva 1615Highway(算法效率--贪心 区间选点问题)