多会场活动安排问题(贪心思想)

多会场活动安排

要求:
  在足够多的会场里安排一批活动,希望使用的会场个数最少

package June21;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class w0629_study2 {
    public static int s[];//活动开始时间
    public static int f[];//活动结束时间
    public static int n;//活动数量
    public static boolean flag[];//活动是否已经被访问
    public static int num = 0;//会场数目

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入需要举办活动的个数:");
        n = in.nextInt();
        s = new int[n];
        f = new int[n];
        System.out.println("请输入每场活动的开始时间:");
        for (int i = 0; i < n; i++) {
            s[i] = in.nextInt();
        }
        System.out.println("请输入每场活动的结束时间:");
        for (int i = 0; i < n; i++) {
            f[i] = in.nextInt();
        }

        flag = new boolean[n];
        for (int i = 0; i < n; i++) {
            flag[i] = false;
        }
		//这个地方大家可以使用复杂度比较低的排序算法,当时为了赶实验进度,选择了这个简单的排序算法
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                if (f[i] >= f[j]) {
                    int tempf = f[i];
                    int temps = s[i];
                    f[i] = f[j];
                    s[i] = s[j];
                    f[j] = tempf;
                    s[j] = temps;
                }
            }
        }
        for (int i = 0; i < n; i++) {
            if (flag[i] == false) {
                System.out.println("活动选择为:"+meetingplace(flag));
                num++;
            }
        }
        System.out.println("最少需要的会场个数为:" + num);
    }

    public static ArrayList<Integer> meetingplace(boolean flag[]) {
        ArrayList<Integer> list = new ArrayList<>();
        int firstlyJoined = 0;
        int recentlyJoined;//最近加入的活动编号
        for (int i = 0; i < flag.length; i++) {
            //找到第一个没有被加入的活动
            if (flag[i] == false) {
                firstlyJoined = i;
                break;
            }
        }
        recentlyJoined = firstlyJoined;
        list.add(recentlyJoined);
        flag[recentlyJoined] = true;
        for (int k = firstlyJoined + 1; k < n; k++) {
            if (flag[k] == false) {
                //在没有被加入会场的活动选择加入
                if (s[k] >= f[recentlyJoined]) {
                    recentlyJoined = k;//更新最近加入的活动编号
                    flag[recentlyJoined] = true;
                    list.add(recentlyJoined);
                }
            }
        }
        return list;
    }
}

算法思想:
  在会场活动安排这个问题中,首先把所有的活动通过结束时间升序排序,选择第一个活动I1加进第一个会场,在活动I1被接受后,标记活动I1已经被安排,所有与I1不相容的活动和已经被安排好的活动都会被拒绝,找到第一个满足活动开始时间大于等于I1结束时间的活动,即接受此活动,标记此活动已经被安排,并把与此活动不相容的活动和已经安排好的活动都拒绝,以此为循环,即可找到第一个会场可以安排的最大活动数目,这些已经被安排的活动都已经被标记,不会在下一个会场中被访问,在下个会场中,首先找到第一个未被访问过的活动,接受此活动,并找到第一个与此不相容的活动,再接受这个活动,最后也使这个会场安排的活动最大化。就这样,我们不停地增加会场数,直至所有的活动都被安排,即可得到最少的会场数目。
  总的来说,本算法的思想是让每个会场举办都活动数目都尽可能的多,这样,所使用的会场数目就最少,属于贪心思想。最后构造的最优解构成就是依次输出每个会场所安排的活动。

流程图
在这里插入图片描述
运行结果(截图)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值