任务时间表(task.cpp/pas)
题目描述(Description):
一个单位时间任务是恰好需要一个单位时间完成的任务。给定一个单位时间任务的有限集S。关于S的一个时间表用于描述S中单位时间任务的执行次序。时间表中第1个任务从时间0开始执行直至时间1结束,第2个任务从时间1开始执行至时间2结束,…,第n个任务从时间n-1开始执行直至时间n结束。
具有截止时间和误时惩罚的单位时间任务时间表问题可描述如下。
(1) n个单位时间任务的集合S={1,2,…,n};
(2) 任务i的截止时间di,1≤i≤n,1≤ di≤n,即要求任务i在时间di之前结束;
(3) 任务i的误时惩罚wi,1≤i≤n,即任务i未在时间di之前结束将招致wi的惩罚;
若按时完成则无惩罚。
现给定n个单位时间任务,各任务的截止时间di,各任务的误时惩罚wi,1≤i≤n,编程对给定的S计算一个最优时间表,使得总误时惩罚达到最小。
输入文件(task.in):
第一行是正整数n(1≤n≤500),表示任务数;
第二行有n个正整数,分别表示各任务的截止时间di(1≤di≤500);
第三行有n个正整数,分别表示各任务的误时惩罚wi(1≤wi≤1000)。
输出文件(task.out):
最小的总误时惩罚数。
Sample Input Case 1:
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10
Sample Output Case 1:
50
===========================
原来做过一道类似的题目
==============================
type
node=record
d,w:longint;
end;
var
n:longint;
ti:array[1..500]of node;
dui:array[1..500]of longint;
dui_s:longint;
procedure init;
begin
assign(input,'task.in');
assign(output,'task.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure qsort(s,t:Longint);
var
i,j:longint;
x,tem:node;
begin
i:=s; j:=t;
x:=ti[(s+t)shr 1];
repeat
while (x.d<ti[j].d) or ((x.d=ti[j].d)and(x.w<ti[j].w)) do dec(j);
while (ti[i].d<x.d) or ((x.d=ti[i].d)and(ti[i].w<x.w)) do inc(i);
if i<=j then begin tem:=ti[i]; ti[i]:=ti[j]; ti[j]:=tem; inc(i); dec(j); end;
until i>j;
if i<t then qsort(i,t);
if s<j then qsort(s,j);
end;
procedure adjust(k:longint);
var
r:longint;
tem:longint;
begin
r:=k shr 1;
while (r>0)and(ti[dui[r]].w<ti[dui[k]].w) do
begin
tem:=dui[r]; dui[r]:=dui[k]; dui[k]:=tem;
k:=r; r:=k shr 1;
end;
end;
procedure shift(r,n:longint);
var
k:longint;
tem:longint;
begin
k:=r*2;
if (k+1<=n)and(ti[dui[k+1]].w>ti[dui[k]].w) then inc(k);
while (k<=n)and(ti[dui[k]].w>ti[dui[r]].w) do
begin
tem:=dui[k]; dui[k]:=dui[r]; dui[r]:=tem;
r:=k;
k:=r*2;
if (k+1<=n)and(ti[dui[k+1]].w>ti[dui[k]].w) then inc(k);
end;
end;
procedure main;
var
i:longint;
t:longint;
num:longint;
ans,ans_t:longint;
begin
readln(n);
ans:=0;
for i:=1 to n do read(ti[i].d);
for i:=1 to n do begin read(ti[i].w); ans:=ans+ti[i].w; end;
qsort(1,n);
t:=ti[n].d;
dui_s:=1;
dui[1]:=n;
num:=n-1;
ans_t:=0;
for i:=t downto 1 do
begin
while (num>=1)and(ti[num].d=i) do
begin
inc(dui_s);
dui[dui_s]:=num;
adjust(dui_s);
dec(num);
end;
if dui_s>=1 then
begin
inc(ans_t,ti[dui[1]].w);
dui[1]:=dui[dui_s];
dec(dui_s);
shift(1,dui_s);
end;
end;
writeln(ans-ans_t);
end;
begin
init;
main;
terminate;
end.