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.
posted @ 2012-02-19 23:37  你滴韩王  阅读(216)  评论(0)    收藏  举报