4-18 非单位时间任务安排问题
问题描述
具有截止时间和误时惩罚的任务安排问题可描述如下。
(1) 给定 n 个任务的集合
;
(2) 完成任务i需要
时间,
;
(3) 任务 i 的截止时间
,
,即要求任务 i 在时间
之前结束;
(4) 任务 i 的误时惩罚
,
,即任务 i 未在时间
之前结束将招致
的惩罚;
若按时完成则无惩罚。
任务安排问题要求确定 S 的一个时间表(最优时间表)使得总误时惩罚达到最小。
对于给定的 n 个任务,编程计算总误时惩罚最小的最优时间表。
数据输入:
第 1 行是 1 个正整数 n,表示任务数。接下来的 n 行中,每行有 3 个正整数 a,b,c,表示完成相应任务需要时间 a,截止时间为 b,误时惩罚为 c。
Java
import java.util.*;
public class FeiDanWeiShiJianRenWuAnPai {
private static class TASK implements Comparable{
int needTime;
int deadline;
int punishment;
public int compareTo(Object t){
TASK task = (TASK) t;
int result = Integer.compare(deadline, task.deadline);//升序
return result;
}
}
private static int n,d;
private static List<TASK> tsk;
private static int[][] f;
private static int MAX = 100000;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
n = input.nextInt();
tsk = new ArrayList<>(n);
for(int i=0; i<n; i++){
TASK t = new TASK();
t.needTime = input.nextInt();
t.deadline = input.nextInt();
t.punishment = input.nextInt();
tsk.add(t);
}
Collections.sort(tsk);
d = tsk.get(n-1).deadline;
f = new int[n][d+1];
for(int i=0; i<n; i++)
for(int j=0; j<=d; j++)
f[i][j] = MAX;
dynamic();
System.out.println(f[n-1][d]);
}
}
private static void dynamic(){
for(int i=0; i<=d; i++)
if(tsk.get(0).needTime <= i)
f[0][i] = 0;
else
f[0][i] = tsk.get(0).punishment;
for(int i=1; i<n; i++){
for(int j=0; j<=d; j++){
f[i][j] = f[i-1][j] + tsk.get(i).punishment;
int jj = tsk.get(i).deadline > j ? j : tsk.get(i).deadline;
if(jj >= tsk.get(i).needTime && f[i][j]>f[i-1][jj-tsk.get(i).needTime])
f[i][j] = f[i-1][jj-tsk.get(i).needTime];
}
}
}
}
Input & Output
7
1 4 70
2 2 60
1 4 50
1 3 40
1 1 30
1 4 20
3 6 80
110
Reference
王晓东《计算机算法设计与分析》(第3版)P135