书的复制

来源:互联网 发布:xalhar哈萨克电影软件 编辑:程序博客网 时间:2024/06/05 00:11

 

书的复制

源程序名            book.???(pas, c, cpp)

可执行文件名        book.exe

输入文件名          book.in

输出文件名          book.out

【问题描述】

       现在要把m本有顺序的书分给k给人复制(抄写),每一个人的抄写速度都一样,一本书不允许给两个(或以上)的人抄写,分给每一个人的书,必须是连续的,比如不能把第一、第三、第四本书给同一个人抄写。

       现在请你设计一种方案,使得复制时间最短。复制时间为抄写页数最多的人用去的时间。

【输入】

       第一行两个整数m,k;(k≤m≤500)

       第二行m个整数,第i个整数表示第i本书的页数。

【输出】

       共k行,每行两个整数,第i行表示第i个人抄写的书的起始编号和终止编号。k行的起始编号应该从小到大排列,如果有多解,则尽可能让前面的人少抄写。

【样例】

       book.in                                      book.out

       9 3                                             1 5

       1 2 3 4 5 6 7 8 9                      6 7

                                                          8 9

==============================

f[i,j]表示前i本书,j个人抄用去的最小的最大时间。

f[i,j]:=max(f[i,j],f[l,j-1]+sum[i]-sum[l]);

--------------------------------------------------

对于多解的处理,相当于是一个贪心,

从后面开始算起,保证后面的值<=最小的最大时间...

记录数组输出就可..

=========================================

type  node=record         s,t:longint;       end;var  m,k:longint;  a,s:array[0..100]of longint;  f:array[0..100,0..100]of longint;  ans:array[1..100]of node;  ans_s:longint;procedure init;begin  assign(input,'book.in');  assign(output,'book.out');  reset(input); rewrite(output);end;procedure terminate;begin  close(input); close(output);  halt;end;function min(a,b:longint):longint;begin  if a>b then exit(b);  exit(a);end;function max(a,b:longint):longint;begin  if a>b then exit(a);  exit(b);end;procedure main;var  i,j,k:longint;  k1:longint;  t:longint;  l,r:longint;begin  readln(m,k);  s[0]:=0;  for i:=1 to m do    begin      read(a[i]);      s[i]:=s[i-1]+a[i];    end;  fillchar(f,sizeof(f),$7);  f[0,0]:=0;  for i:=1 to k do    for j:=1 to m do      begin        for k1:=j-1 downto i-1 do          begin            f[i,j]:=min(f[i,j],max(f[i-1,k1],s[j]-s[k1]));          end;      end;  t:=f[k,m];  ans_s:=0;  r:=m; l:=m;  while ans_s<k-1 do    begin      if s[r]-s[l-1]=t then        begin          inc(ans_s);          ans[ans_s].t:=r;          ans[ans_s].s:=l;          dec(l);          r:=l;          //头尾指针左移        end        else if s[r]-s[l-1]>t then              begin                inc(ans_s);                ans[ans_s].t:=r;                ans[ans_s].s:=l+1;                r:=l;              end              else dec(l);    end;  if ans_s=k-1 then    begin      inc(ans_s);      ans[ans_s].s:=1;      ans[ans_s].t:=r;    end;  for i:=ans_s downto 1 do    writeln(ans[i].s,' ',ans[i].t);end;begin  init;  main;  terminate;end.