POJ P2442 Sequence

来源:互联网 发布:安知玉如意txt网盘 编辑:程序博客网 时间:2024/06/05 08:36

题目大意:给你T组n*m的矩阵,每组矩阵每行取一个元素,组成一个包含n个元素的序列,一共有n^m种序列,让你求出序列和最小的前n个序列的序列和。

堆:
1.把第T组数据的第一组数组给记录。
2.从第二组到第N组开始,a[j]表示前i-1组第j大的序列和,i为当前第i组。
3.把前M大的a[j],跟这组数组组合,如果有一个比第M大的小就替换,然后替换堆并且做下移操作,因为做的是大头堆。
4.把最后求出来的f数组(堆)给排序一遍作为前i组数据前M大的序列和,加入到a数组中,做下一组数组。

var   a,b,o,f:array [0..2001] of longint;   t,i,j,k,l,n,m:longint;procedure up(x:longint);begin   if x=1 then exit;   repeat     if f[x]>f[x div 2]       then begin               f[0]:=f[x];               f[x]:=f[x div 2];               f[x div 2]:=f[0];            end       else break;     x:=x div 2;  until x=0;end;procedure down(x:longint);begin  if 2*x>m then exit;  repeat    x:=2*x;    if x+1<=m then       if f[x]<f[x+1] then inc(x);       if f[x div 2]<f[x] then          begin             f[0]:=f[x];             f[x]:=f[x div 2];             f[x div 2]:=f[0];          end        else break;  until 2*x>m;end;procedure qsort(l,r:longint);var  i,j,mid:longint;begin  if l>=r then exit;  i:=l; j:=r;  mid:=o[(l+r) div 2];  repeat    while o[i]<mid do inc(i);    while o[j]>mid do dec(j);    if i<=j then      begin        o[0]:=o[i];        o[i]:=o[j];        o[j]:=o[0];        inc(i); dec(j);      end;  until i>j;  qsort(i,r);  qsort(l,j);end;begin    readln(t);    for i:=1 to t do        begin            fillchar(a,sizeof(a),0);            fillchar(b,sizeof(b),0);            fillchar(f,sizeof(f),0);            fillchar(o,sizeof(o),0);            readln(n,m);            for j:=1 to m do read(o[j]);            qsort(1,m);            a:=o;            readln;            for j:=1 to n-1 do                begin                   for k:=1 to m do read(o[k]);                   readln;                   qsort(1,m);                   b:=o;                   for k:=1 to m do                       begin                           f[k]:=a[k]+b[1];                           up(k);                       end;                   for k:=2 to m do                       for l:=1 to m do                           if b[k]+a[l]<f[1]                              then begin                                      f[1]:=b[k]+a[l];                                      down(1);                                   end                              else break;                   o:=f;                   qsort(1,m);                   a:=o;                   fillchar(f,sizeof(f),0);            end;          for j:=1 to m do write(a[j],' ');          writeln;        end;end.
1 0
原创粉丝点击