USACO-Chapter1-Section 1.3-Barn Repair (barn1)
【题目描述】
在一个夜黑风高,下着暴风雨的夜晚,farmer John的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没有住满。 牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜。 有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。 自门遗失以后,farmer John必须尽快在牛棚之前竖立起新的木板。 他的新木材供应商将会供应他任何他想要的长度,但是吝啬的供应商只能提供有限数目的木板。 farmer John想将他购买的木板总长度减到最少。
给出:可能买到的木板最大的数目M(1<= M<=50);牛棚的总数S(1<= S<=200); 牛棚里牛的总数C(1 <= C <=S);和牛所在的牛棚的编号stall_number(1 <= stall_number <= S),计算拦住所有有牛的牛棚所需木板的最小总长度。 输出所需木板的最小总长度作为答案。
【输入格式】
1 行: M , S 和 C(用空格分开) ,2 到 C+1行: 每行包含一个整数,表示牛所占的牛棚的编号。
【输出格式】
单独的一行包含一个整数表示所需木板的最小总长度。
【输入样例】
4 50 18 3 4 6 8 14 15 16 17 21 25 26 27 30 31 40 41 42 43
【输出样例】
25
【思路】
贪心策略,反向思考,既然我可以向上加牛栏,那么我就可以倒着把装好的牛栏给PASS掉,比如------------------的牛栏,我要分成4份那么就---|---|--|----------这样子分成三份。那么和就是第一段一直加到第四段,既然我们已经把所有的牛栏都给装好了,完全不必要再次加和。只需要把你断掉的地方减去(因为相当于多算了)。主意,有可能数据给的c<n此时,应该保留n而不是c。
【代码】
时间复杂度:O(n+n*log(n))
空间复杂度:O(n)
- Executing...
- Test 1: TEST OK [0.000 secs, 4180 KB]
- Test 2: TEST OK [0.000 secs, 4180 KB]
- Test 3: TEST OK [0.000 secs, 4180 KB]
- Test 4: TEST OK [0.000 secs, 4180 KB]
- Test 5: TEST OK [0.000 secs, 4180 KB]
- Test 6: TEST OK [0.000 secs, 4180 KB]
- Test 7: TEST OK [0.000 secs, 4180 KB]
- Test 8: TEST OK [0.000 secs, 4180 KB]
- Test 9: TEST OK [0.000 secs, 4180 KB]
- Test 10: TEST OK [0.000 secs, 4180 KB]
- All tests OK.
懒得打形参快排了,直接copy一次,所以代码有些长。
{
ID : c_CaM.19
LANG: PASCAL
TASK: barn1
}
Program CaM(input,output);
Var
a,b:array[0..500000] of longint;
i,c,n,m,s,ans:longint;
Function min(x,y:longint):longint;
Begin
if x<y then exit(x) else exit(y);
End;
Procedure qs(x,y:longint);
Var
i,j,mid,t:longint;
Begin
i:=x; j:=y; mid:=a[(x+y)div 2];
repeat
while a[i]>mid do inc(i);
while a[j]<mid do dec(j);
if i<=j then
Begin
t:=a[i]; a[i]:=a[j]; a[j]:=t;
inc(i); dec(j);
End;
until i>j;
if x<j then qs(x,j);
if i<y then qs(i,y);
End;
Procedure qs_(x,y:longint);
Var
i,j,mid,t:longint;
Begin
i:=x; j:=y; mid:=b[(x+y)div 2];
repeat
while b[i]<mid do inc(i);
while b[j]>mid do dec(j);
if i<=j then
Begin
t:=b[i]; b[i]:=b[j]; b[j]:=t;
inc(i); dec(j);
End;
until i>j;
if x<j then qs_(x,j);
if i<y then qs_(i,y);
End;
Procedure innt;
Begin
assign(input,'barn1.in'); reset(input);
assign(output,'barn1.out'); rewrite(output);
End;
Procedure outt;
Begin
close(input);
close(output);
End;
Begin
innt;
readln(m,s,c);
for i:=1 to c do
readln(b[i]);
qs_(1,c);
for i:=2 to c do
a[i]:=b[i]-b[i-1];
qs(2,c); ans:=b[c]-b[1]+1;
for i:=2 to min(m,c) do
ans:=ans-a[i]+1;
writeln(ans);
outt;
End.
浙公网安备 33010602011771号