又是好久沒更,最近一直在忙雜七雜八的,更一個算法作業吧。
問題
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相容。
活動安排問題就是在所給的活動集合中選出最大的相容活動子集合。
分析
開始最早的方案基本不用考慮,這裏不解釋。
我最初的方法是先找時間間隔最短的,這樣就可以留出足夠多的時間去舉辦別的活動。
但是我忽略了一點,這樣分割出來的很有可能是不間隔的兩段時間段。按照這個規則選取活動的話,取一兩次之後時間可能就被分割成不同大小的不連續小段,這樣肯定不能再用了。
那我們就讓剩餘的時間段連續起來,還要最大,那麼我們就選擇結束時間最早的,這樣留出來的是整塊的時間還挺大。
代碼
/**
* @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;
}
好久沒更新十分抱歉,感到有幫助的話請給個大大的點👍,給我一些些的動力🙏🙏