机密文件

来源:互联网 发布:新红楼梦 知乎 编辑:程序博客网 时间:2024/04/30 07:15

题目描述:OI总部最近得到可靠消息,近日来怪盗基德会再次来OI总部盗窃机密文件(因为是机密,所以不能透露),所以OIER得在怪盗基德来临之前就把文件备份。不过,正好今天OI总部停电了,所以就得人工抄写了。现在,OI总部内一共有M份资料和K个OIER(S),需要将每一份资料都备份一份,M份资料的页数不一定相同(有不同的,也有相同的)。现在,你作为其中的一名OIER,把资料分配给OIER备份,由于人太多了,所以每一名OIER所分配到的资料都必须是连续顺序的,并且每一名OIER的备份速度是相同的。你的任务就是让备份的时间最短,列出最短的方案。数据可能存在多个解,所以,当存在多个解时,让前面的人少备份。

输入:输入文件中的第一行为两个整数M,K,分别表示书本的数目和OIER的人数。
第二行中为由M个分隔的整数构成,分别表示M本书的页数。其中:第i份资料的编号为i。

输出:输出文件中共有K行,每行有两个整数。其中:第i行中表示第i个OIER备份的资料编号的起止。

样例输入:

8 3
1 2 3 4 5 6 7 8



这道题其实就是二分答案,从后往前判断(注意:每个人手里都要有抄写任务,所以要加一个特判:如果剩余人数=剩余书本数,就强制一人一本)。

代码:

var
        n,m,i,j,k,x,y,z,s,ls,l,r,mid:longint;
        a:array[0..1001]of longint;
        f:array[0..1001,1..2]of longint;
function pd(k:longint):boolean;
var
        i,j,x,y,z,s,ls:longint;
        o:array[0..1001,1..2]of longint;
begin
        fillchar(o,sizeof(o),0);
        ls:=0;
        for i:=n downto 1 do
        begin
                if i=n then
                begin
                        inc(o[0,1]);
                        o[o[0,1],1]:=i;
                        inc(ls,a[n]);
                end
                else
                begin
                        if i=m-o[0,1] then
                        begin
                                o[o[0,1],2]:=i+1;
                                inc(o[0,1]);
                                o[o[0,1],1]:=i;
                                o[o[0,1],2]:=i;
                        end
                        else
                        begin
                        if ls+a[i]>k then
                        begin
                                o[o[0,1],2]:=i+1;
                                inc(o[0,1]);
                                if o[0,1]>m then exit(false);
                                o[o[0,1],1]:=i;
                                ls:=a[i];
                        end
                        else inc(ls,a[i]);
                        end;
                end;
        end;
        o[o[0,1],2]:=1;
        f:=o;
        exit(true);
end;
begin
        assign(input,'secret.in');
        reset(input);
        assign(output,'secret.out');
        rewrite(output);
        readln(n,m);
        l:=-maxlongint;
        for i:=1 to n do
        begin
                read(a[i]);
                inc(r,a[i]);
                if a[i]>l then l:=a[i];
        end;
        while l<=r do
        begin
                mid:=(l+r) div 2;
                if pd(mid) then r:=mid-1
                else l:=mid+1;
        end;
        for i:=m downto 1 do
        writeln(f[i,2],' ',f[i,1]);
end.



原创粉丝点击