贪心算法详细介绍(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);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41479464/article/details/88693858