Case03_区间调度问题

Case03——区间调度问题

问题描述:

有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。

限制条件:

1<=n<=100000

1<=si<=ti,=109

样例:

输入

n=5

1,2,4,6,8

3,5,7,9,10

输出

3(选择工作1, 3, 5(可选择性输出))

先理一下题目描述的
1 3 是一个区间;
2 5 是一个区间;
4 7是一个区间;
6 9是一个区间;
8 10是一个区间;
我们可以有以下的方法:
1,找结束时间早的;
2,找开始时间早的;
3,每次选取用时最短的;
4,在可选工作中,每次选取与最小可选工作有重叠的部分;
对于贪心我们可以采取举证取反例的方法
我们可以发现找结束时间最早的是最优的方法
但是我们不能保证每一个开始时间集合,结束时间是有序的,这就用到面向对象的知识了,打包在一起,做对象数组。
并重写CompareTo方法,排序结束时间,如果结束时间一样就,排序开始时间最早的时间

代码如下:

package greed_dynamic;
import static java.lang.Math.min;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Pra {

		public static void main(String[] args) {
			// TODO 自动生成的方法存根
			Scanner sc = new Scanner(System.in);
	        int n = sc.nextInt();
			int[] s = new int[n];
			int[] t = new int[n];
			//处理输入
			for (int i = 0; i < n; i++) {
				s[i] = sc.nextInt();
				
			}
			for (int i = 0; i < n; i++) {
				t[i] = sc.nextInt();
			}
			//创建对象数组
			job[] jobs = new job[n];
			for (int i = 0; i < t.length; i++) {
				jobs[i] = new job(s[i],t[i]);
			}
			System.out.println(f(n,jobs));
			
                                                				
			
		}
		private static int f(int n, job[] jobs) {
			// TODO 自动生成的方法存根
			int cnt = 1;
			//第一个任务必选
			int y = jobs[0].t;
			for (int i = 0; i < jobs.length; i++) {
				//找大于结束时间最早的开始时间,并更新与之对应的结束时间
				if (jobs[i].s > y) {
					cnt++;
					y = jobs[i].t;
				}
				
			}
			return cnt;
			
		}
		public static class job implements Comparable<job>{
            int s;
            int t;
            //构造函数
            public job (int s,int t) {
            	this.s = s;
            	this.t = t;
            }
            //重写compareTo方法
			public int compareTo(job other) {
				// TODO 自动生成的方法存根
				int x = this.t - other.t;//对结束时间排序
				if (x == 0) {//结束时间一致,排序开始时间
					return this.s - other.s;
				}
				return x;
			}
			
		}
		
	    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值