贪心算法 区间覆盖问题java版

贪心算法

贪心算法的定义:选取当前最优策略,最终找到最优解
贪心算法的难点在于,要解决当前最优未必是整体最优的问题

贪心算法之区间覆盖问题

先上题目:

农夫约翰正在分配他的N头(1 <= N <= 25,000)头母牛在谷仓周围做一些清洁工作。他一直想让一头母牛进行清理工作,并将一天分为T班(1 <= T <= 1,000,000),第一个是班1,最后一个是T班。

每头母牛只能在一定间隔内使用。白天进行清洁工作的次数。任何被选定负责清洁工作的母牛将在整个间隔时间内工作。

您的工作是帮助农夫约翰分配一些奶牛到班次,以便(i)每个班次至少分配一头奶牛,并且(ii)尽可能少地母牛参与清洁工作。如果无法为每个班次分配一头母牛,请打印-1。
输入
*第1行:两个以空格分隔的整数:N和T

*第2..N + 1行:每行包含母牛可以工作的时间间隔的开始和结束时间。母牛在开始时间开始工作,在结束时间之后结束。
输出
*第1行:如果无法为每个班次分配一头母牛,农夫约翰需要雇用的最小母牛数或-1。

样本输入
3 10
1 7
3 6
6 10

样本输出
2
暗示
此问题有大量输入数据,请使用scanf()而不是cin读取数据,以避免超过时间限制。

输入详细信息:

有3头母牛和10个班次。#1奶牛可以上班1..7,#2牛可以上班3..6,而#3牛可以上班6..10。

输出详细信息:

通过选择1号和3号奶牛,所有班次都包括在内。没有办法使用少于2头母牛来覆盖所有班次。

这是一道典型的区间覆盖问题,题目的大体意思就是,第一行输入的两个参数为,牛的数量,第二个为总的工作区间。后面依次为每头牛的工作的开始时间和结束时间。要求最少分配几头牛可以覆盖所有工作区间,即可以完成所有工作。
在这里插入图片描述
图片上为大致结题思路,代码如下:

package demo;

import java.util.Scanner;

public class 贪心算法之区间覆盖问题 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();// 输入牛的数量
		int m = sc.nextInt();// 输入工作总区间
		Job[] jb = new Job[n];
		// 初始化job数组,否则会报空指针异常
		for (int i = 0; i < n; i++) {
			jb[i] = new Job(sc.nextInt(), sc.nextInt());
		}

		int start = 1;
		int end = 1;
		int count = 1;
		for (int i = 0; i < n; i++) {
			int left = jb[i].left;
			int right = jb[i].right;
			if (i == 0 && jb[i].left > start)
				break;
			if (left <= start) {
				end = Math.max(end, right);
			} else {
				count++;
				start = end + 1;
				if (left > end) {
					break;
				} else {
					end = Math.max(end, right);
				}
			}
			if (end >= m)
				break;
		}
		if (end >= m) {
			System.out.println(count);
		} else
			System.out.println(-1);

	}

	private static class Job implements Comparable<Job> {// 要比较每段区间末尾,同时要关联区间开端,就要把区间的两端进行关联,进行封装是比较合适的
		int left, right;

		public Job(int left, int right) {
			this.left = left;
			this.right = right;
		}

		@Override
		public int compareTo(Job o) {
			// TODO Auto-generated method stub
			int x = this.left - o.left;
			if (x == 0) {
				return this.right - o.right;
			} else
				return x;

		}

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值