问题描述: |
一台精密仪器的工作时间为 n 个时间单位。与仪器工作时间同步进行若干仪器维修程序。一 旦启动维修程序,仪器必须进入维修程序。如果只有一个维修程序启动,则必须进入该维修 程序。如果在同一时刻有多个维修程序,可任选进入其中的一个维修程序。维修程序必须从 头开始,不能从中间插入。一个维修程序从第s个时间单位开始,持续 t个时间单位,则该维 修程序在第s+t-1 个时间单位结束。为了提高仪器使用率,希望安排尽可能少的维修时间。 | |
编程任务: |
对于给定的维修程序时间表,编程计算最优时间表。 | |
数据输入: |
由文件input.txt给出输入数据。第 1 行有2 个正整数n和 k。n表示仪器的工作时间单位;k是 维修程序数。接下来的k行中,每行有2 个表示维修程序的整数s和 t,该维修程序从第s个时 间单位开始,持续t个时间单位。 | |
结果输出: |
将计算出的最少维修时间输出到文件 output.txt。 | |
样例: |
15 6 1 2 1 6 4 11 8 5 8 1 11 5 |
11 |
核心思想: |
尼克的任务,f[i]=max{f[i],f[a[k].st+a[k].ed]}/f[i]=f[i+1]+1 先按开始时间排序,然后倒着枚举相同开始时间的逐个比较,不同的+1,最后输出n-f[1] |
type
act=record
st,ed:longint;
end;
var
a:array[0..10000]of act;
f:array[0..1000000]of longint;
n,i,j,k:longint;
procedure qsort(l,r:longint);
var
i,j,k:longint;
t:act;
begin
i:=l;j:=r;
k:=a[(l+r)shr 1].st;
repeat
while a[i].st<k do inc(i);
while a[j].st>k do dec(j);
ifi<=j then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
inc(i);dec(j);
end;
until i>j;
ifi<r then qsort(i,r);
ifj>l then qsort(l,j);
end;
function max(a,b:longint):longint;
begin
ifa<b then exit(b);
exit(a);
end;
begin
assign(input,'p318.in');reset(input);
assign(output,'p318.out');rewrite(output);
readln(n,k);
fori:=1 to k do
begin
readln(a[i].st,a[i].ed);
end;
qsort(1,k);
fillchar(f,sizeof(f),0);
fori:=n downto 1 do
ifi<>a[k].st then f[i]:=f[i+1]+1
else
while i=a[k].st do
begin
f[i]:=max(f[i],f[a[k].st+a[k].ed]);
dec(k);
end;
writeln(n-f[1]);
close(input);close(output);
end.
题目来源:《算法设计与分析》第三章动态规划