贪心算法详细介绍(java)以及会场安排问题
用贪心选择策略解会场安排问题。
贪心算法重要的两个性质:贪心选择性质和最优子结构性质。
1、 问题的贪心选择性质
证明:首先将会场安排问题数学化,设有n个活动的集合 e= { 1 ,2 ,…,n },每个活动 i 都有一个要求使用该会场的起始时问si 和一个结束时问fi 。即k是所需最少会场的个数。设活动已排序,( a1 , a2 , … ,ak )是所需要的k个已安排了活动的会场。①当k = 1时,也就是所有的活动在一个会场里相容,a1 是满足贪心选择性质的最优解;②当k>= 2时,取b1=a1,bk=ak (即bk是安排了m个活动的一个会场,(n-m)个活动都安排在b1 到bk-1个会场里)。就是(n-m)个活动安排需要(k -1)个会场。则(b1,b2 ,…,bk-1 )是(n - m)个活动可行解。另一方面,由{( a1 ,a2,…,ak)-ak}=(b1,b2,…,bk-1)知,(b1,b2,…,bk-1)也是满足贪心选择性质的最优解,所以,会场安排问题具有贪心选择性质。
7-62 会场安排问题 (20 分)
题目来源:王晓东《算法设计与分析》
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的 贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个 顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小 会场数。)
输入格式:
第一行有 1 个正整数k,表示有 k个待安排的活动。 接下来的 k行中,每行有 2个正整数,分别表示 k个待安排的活动开始时间和结束时间。时间 以 0 点开始的分钟计。
输出格式:
输出最少会场数。
输入样例:
5
1 23
12 28
25 35
27 80
36 50
输出样例:
在这里给出相应的输出。例如:
3
反思:这道题,我其实是想哭的,因为写了几个小时都发现是有的测试点过不去,pta不得不说,真不好,看不见测试点,而且不知道那个错,很无语,自己试了n次发现答案都是对的,但是就是过不去。百度了n遍没啥用,最后随便去改改 一点一点调试,他满分了 ,不得不说,坚持还是很重要的。
思路:这道题就是典型的一个贪心算法的实现。第一步二个数组,一个开始时间一个结束时间,然后排序数组,然后就是贪心算法的实现了。这道题也就是后面一个开始时间需要大于其上一个结束时间。接下来我将附两个代码,一个是测试点没过去一个是过去的代码:
第一个没过去的:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sr = new Scanner(System.in);
int n = sr.nextInt();
int a[] = new int [n];
int b[] = new int [n];
for(int i=0;i<n;i++) {
a[i]=sr.nextInt();
b[i]=sr.nextInt();
}
// int count=1;
Greedy(n,a,b);
}
private static void Greedy(int n,int start[],int end[]){
int j=0;
int count = 0;
for (int i=1;i<n;i++){
if (start[i]>=end[j]){
j=i; // 注意这部分
}else{
count++;
}
}
if (n==0){
System.out.println(count);
}else{
System.out.println(count+1);
}
}
}
AC代码:
import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sr = new Scanner(System.in); int n = sr.nextInt(); int a[] = new int [n]; int b[] = new int [n]; for(int i=0;i<n;i++) { a[i]=sr.nextInt(); b[i]=sr.nextInt(); } Arrays.sort(a); Arrays.sort(b); Greedy(n,a,b); } private static void Greedy(int n,int start[],int end[]){ int j=0; int count = 0; for (int i=0;i<n;i++){ if (start[i]<end[j]){ count++; }else{ j++; } } System.out.println(count); } }