活動安排問題(貪心、Java)

活動安排問題(貪心、Java)

又是好久沒更,最近一直在忙雜七雜八的,更一個算法作業吧。

問題

X軸上有N條線段,每條線段有1個起點S和終點E。最多能夠選出多少條互不重疊的線段。(注:起點或終點重疊,不算重疊)。

或者

設有n個活動的集合E={1,2,…,n},其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有一個活動能使用這一資源。每個活動i都有一個要求使用該資源的起始時間si和一個結束時間fi,且si<fi。如果選擇了活動i,則它在半開時間區間[si ,fi )內佔用資源。若區間[si ,fi )與區間[sj,fj )不相交,則稱活動i與活動j是相容的。當 si ≥ fj 或 sj ≥ fi 時,活動i與活動j相容。
活動安排問題就是在所給的活動集合中選出最大的相容活動子集合。
圖片來自https://www.jianshu.com/p/5a97bcc407fa?tdsourcetag=s_pctim_aiomsg

分析

開始最早的方案基本不用考慮,這裏不解釋。

我最初的方法是先找時間間隔最短的,這樣就可以留出足夠多的時間去舉辦別的活動。
但是我忽略了一點,這樣分割出來的很有可能是不間隔的兩段時間段。按照這個規則選取活動的話,取一兩次之後時間可能就被分割成不同大小的不連續小段,這樣肯定不能再用了。

在這裏插入圖片描述
那我們就讓剩餘的時間段連續起來,還要最大,那麼我們就選擇結束時間最早的,這樣留出來的是整塊的時間還挺大。
在這裏插入圖片描述

代碼

/**
 * @ClassName ActivityArrangement
 * @Description 活動安排問題 貪心算法 不考慮整體最優而專注局部最優解
 *
 *設有n個活動的集合E={1,2,…,n},其中每個活動都要求使用同一資源,如演講會場等,
 * 而在同一時間內只有一個活動能使用這一資源。
 * 每個活動i都有一個要求使用該資源的起始時間si和一個結束時間fi,且si<fi。
 * 如果選擇了活動i,則它在半開時間區間[si ,fi )內佔用資源。若區間[si ,fi )與區間[sj,fj )不相交,
 * 則稱活動i與活動j是相容的。當 si ≥ fj 或 sj ≥ fi 時,活動i與活動j相容。
 * 活動安排問題就是在所給的活動集合中選出最大的相容活動子集合。
 *
 *
 * @author 滑技工廠 https://blog.csdn.net/qq_41718454
 * @date 2020/6/5
 * @version 1.0
 */
public class ActivityArrangement {

    /*
     * @Title chooseActivity
     * @Description 選擇活動方法
     * @author 滑技工廠
     * @Date 2020/6/5
     * @param [activities]
     * @return boolean[] 返回活動選擇數組
     * @throws
     */
    public static boolean[] chooseActivity(Activity[] activities) {
        int n = activities.length;
        //用來表示原活動序列(未排序)是否被選中
        boolean[] flags = new boolean[n];

        //把序列按照結束時間進行升序排序
        Arrays.sort(activities);

        //結束時間指針
        int flag = 0;

        for (int i = 0; i < n; i++) {
            //排序之後,如果一個活動的開始時間在指針之後或相等,那麼便可以舉辦這個活動
            if (activities[i].starttime>=flag){
                //舉辦活動 更新結束時間指針
                flag = activities[i].finaltime;
                flags[activities[i].index] = true;
            }
        }
        return flags;
    }


    public static void main(String[] args) {
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
        int n = sc.nextInt();
        Activity activities[] = new Activity[n];

        for (int i = 0; i < n; i++) {
            activities[i] = new Activity();
            activities[i].index = i;
            activities[i].starttime = sc.nextInt();
        }
        for (int i = 0; i < n; i++) {
            activities[i].finaltime = sc.nextInt();
        }

        boolean[] flags = chooseActivity(activities);

        for (boolean flag : flags) {
            System.out.print(flag+" ");
        }

    }

}
/**
 * @ClassName Activity
 * @Description 活動類
 * @author 滑技工廠 https://blog.csdn.net/qq_41718454
 * @date 2020/6/5
 * @version 1.0
 */
class Activity implements Comparable<Activity> {
    int index;
    int starttime;
    int finaltime;
    /*
     * @Title compareTo
     * @Description 排序方法
     * @author 滑技工廠
     * @Date 2020/6/5
     * @param [activity]
     * @return int 1表示this對象要排前面 -1表示不排前面
     * @throws
     */
    @Override
    public int compareTo(Activity activity) {
        if (activity.finaltime > this.finaltime)
            return -1;
        else if (activity.finaltime == this.finaltime)
            return 0;
        else
            return 1;
    }

好久沒更新十分抱歉,感到有幫助的話請給個大大的點👍,給我一些些的動力🙏🙏

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章