【贪心+堆】锯木

锯木(cut.c/cpp/pas)

【题目描述】

LazyChild需要将一根非常长的木棒切成n段,每段的长度分别为L1L2LN个长度单位。∑Li(I= 12N)恰好就是原木棒的长度。我们认为切割时仅在整数点处切且没有木材损失。

LazyChild发现,每一次切割花费的体力与该木棒的长度成正比,不妨设切割长度为1的木棒花费1单位体力。

LazyChild想请你帮他计算出最少要多少体力。

【输入文件】

第一行一个整数n

第二行n个整数,分别表示L1L2LN

【输出文件】

一行一个整数表示,LazyChild要付出的最少体力值。

【样例输入】

4

3 5 7 11

【样例输出】

49

【数据规模和约定】

对于30%的数据,n <= 10

对于100%的数据,n <= 100000Li<= 1000

 

【考察点】

贪心策略+数据结构

【思路】

换一个名字,这货叫做果子合并

【提交情况】

2167组嘲讽我吧……

【经验】

骚年别冲动……开堆得时候空间记得*4

【收获】

考试千万不能激动……

 

ACCode

Program cut;

Var

       n,size:longint;

       heap:array[0..400010]of longint;

Procedure terminate;

begin

       close(input);

       close(output);

       halt;

end;

 

Procedure insert(x:longint);

var

       i,c:longint;

begin

       inc(size);

       i:=size;

       heap[size]:=x;

       while (i>1)and(x<heap[i>>1])do 

       begin

              c:=heap[i];

              heap[i]:=heap[i>>1];

              heap[i>>1]:=c;

              i:=i>>1;

       end;

end;

 

Procedure delete;

var

       i,j,x,c:longint;

begin

       heap[1]:=heap[size];

       i:=1;

       j:=2;

       x:=heap[1];

       dec(size);

 

       if (heap[j]>heap[j+1]) then j:=j+1;

              

       while (x>heap[j])and(j<=size) do

       begin

              c:=heap[i];

              heap[i]:=heap[j];

              heap[j]:=c;

              i:=j;

              j:=i<<1;

              if heap[j+1]<heap[j] theninc(j);

       end;

end;

 

Procedure init;

var

       i,x:longint;

begin

       assign(input,'cut.in');

       assign(output,'cut.out');

       reset(input);

       rewrite(output);

 

       readln(n);

       for i:=1 to n do

       begin

              read(x);

              insert(x);

       end;

end;

 

Procedure main;

var

       i,tot,a,b:longint;

begin

       tot:=0;

       for i:=1 to n-1 do

       begin

              a:=heap[1];

              delete;

              b:=heap[1];

              delete;

              tot:=tot+a+b;

              insert(a+b);

       end;

 

       writeln(tot);

end;

 

Begin

       init;

       main;

       terminate;

End.




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值