切换到宽版
  • 5850阅读
  • 6回复

求助!!合并果子!!! [复制链接]

上一主题 下一主题
离线贾森
 
只看楼主 倒序阅读 0 发表于: 2007-11-09
who can tell me how to do it?
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。


每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。


因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。


例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。


【输入文件】


输入文件fruit.in包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。


【输出文件】


输出文件fruit.out包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。


【样例输入】


3
1 2 9


【样例输出】


15


【数据规模】


对于30%的数据,保证有n<=1000:
对于50%的数据,保证有n<=5000;
对于全部的数据,保证有n<=10000。
离线121371490
只看该作者 1 发表于: 2007-11-09
const maxn=20000;
var i,k,n:integer;
    sum,temp,temp1:longint;
    a:array[1..maxn] of longint;
    ha,hb,tb:integer;
procedure adjust(i,n:integer);
var temp:longint;j:integer;
begin
    while i<=n div 2 do begin
        j:=i+i;
        if j<n then if a[j]>a[j+1] then j:=j+1;
        if a<a[j] then break
          else begin temp:=a;a:=a[j];a[j]:=temp;i:=j;end;
    end;
end;
procedure heap_sort(n:integer);
var temp:longint;i:integer;
begin
    for i:=n div 2 downto 1 do adjust(i,n);
    for i:=n-1 downto 1 do begin
        temp:=a[i+1];a[i+1]:=a[1];a[1]:=temp;
        adjust(1,i);
    end;
end;
begin
    readln(n);
    for i:=1 to n do read(a);
    heap_sort(n);
    sum:=0;temp:=0;k:=0;
    ha:=n;hb:=n;tb:=n+1;
    while (ha>=1) or (hb>=tb) do begin
        k:=k+1;
        if ha<1 then begin
            temp1:=a[hb];
            hb:=hb-1;
          end
        else if hb<tb then begin
            temp1:=a[ha];
            ha:=ha-1;
          end
        else if a[ha]<a[hb] then begin
            temp1:=a[ha];
            ha:=ha-1;
          end
        else begin
            temp1:=a[hb];
            hb:=hb-1;
          end;
        temp:=temp+temp1;
        if k mod 2=0 then begin
          sum:=sum+temp;
          tb:=tb-1;a[tb]:=temp;
          temp:=0;
          end;
    end;
    writeln(sum);
end.
离线clwxzh57
只看该作者 2 发表于: 2007-11-09
合并石子问题变种
离线fchqq
只看该作者 3 发表于: 2007-11-09
不是啊。。。记得贪心就可以了。。
不一定合并相邻啊。。
离线luyiqu
只看该作者 4 发表于: 2007-11-10
  1. program luyi;
  2.   var
  3.     a,b:array[1..40000] of longint;
  4.     n,i,j,a1,a2,a3,b1,b2,b3,s,q,w:longint;
  5.   procedure qsort(l,r:longint);
  6.     var
  7.       l1,r1,m,x:longint;
  8.     begin
  9.       if l<=r then
  10.         begin
  11.           m:=a[random(r-l)+l];
  12.           l1:=l;
  13.           r1:=r;
  14.           while l1<=r1 do
  15.             begin
  16.               while a[l1]<m do inc(l1);
  17.               while a[r1]>m do dec(r1);
  18.               if r1>=l1 then
  19.                 begin
  20.                   x:=a[l1];
  21.                   a[l1]:=a[r1];
  22.                   a[r1]:=x;
  23.                   inc(l1);
  24.                   dec(r1);
  25.                 end;
  26.             end;
  27.           if l<r1 then qsort(l,r1);
  28.           if l1<r then qsort(l1,r);
  29.         end;
  30.     end;
  31.   begin
  32.     read(n);
  33.     randomize;
  34.     for i:=1 to n do read(a[i]);
  35.     qsort(1,n);
  36.     b[1]:=a[1]+a[2];
  37.     s:=b[1];a[1]:=0;a[2]:=0;
  38.     a1:=3;a2:=n; a3:=n-2;b3:=1;
  39.     b1:=1; b2:=1;
  40.     for i:=3 to n do
  41.       begin
  42.         q:=maxlongint;
  43.         if a3=0 then
  44.           begin
  45.             a1:=1;a2:=0;
  46.             for j:=b1 to b2 do
  47.               begin
  48.                 inc(a2);
  49.                 a[a2]:=b[j];
  50.                 b[j]:=0;
  51.               end;
  52.             a3:=b3;
  53.             b3:=0;
  54.             b1:=1;b2:=0;
  55.           end;
  56.         if (a[a1]+a[a1+1]<q)and(a3>1) then begin q:=a[a1]+a[a1+1];w:=1;end;
  57.         if (a[a1]+b[b1]<q)and(a3>0)and(b3>0) then begin q:=a[a1]+b[b1];w:=2;end;
  58.         if (b[b1]+b[b1+1]<q)and(b3>1) then begin q:=b[b1]+b[b1+1];w:=3;end;
  59.         s:=s+q;
  60.         inc(b2);inc(b3);
  61.         b[b2]:=q;
  62.         if w=1 then begin a[a1]:=0;a[a1+1]:=0;a1:=a1+2;a3:=a3-2; end else
  63.         if w=2 then begin a[a1]:=0;b[b1]:=0;inc(a1);inc(b1);dec(a3);dec(b3);end else
  64.         if w=3 then begin b[b1]:=0;b[b1+1]:=0;b1:=b1+2;b3:=b3-2; end;
  65.       end;
  66.     if n=1 then writeln('0') else writeln(s);
  67.   end.
离线genius
只看该作者 5 发表于: 2007-11-10
哈夫曼树啊~~最优二叉树
离线prb1989
只看该作者 6 发表于: 2007-11-12
huffman
快速回复
限100 字节
 
上一个 下一个