[二分答案] Copying Books

上次做到那个收入计划的时候就提到了这道题目,在POJ上是让输出方案,并且保证前面的人赋值的书稿尽量多。所以不需要SJ。

具体实现就是先二分出正确的答案,然后根据答案从后往前进行贪心划分。

[pascal 代码]

VAR
        A,WAY:ARRAY[0..100000]OF LONGINT;
        N,M,L,R,MID,I,J,TOT,T,IT:LONGINT;
FUNCTION CHECK(P:LONGINT):BOOLEAN;
 VAR
        PRE,I:LONGINT;
 BEGIN
        TOT:=M;
        PRE:=0;
        I:=1;
        WHILE I<=N DO
                BEGIN
                        IF PRE+A[I]<=P THEN
                                BEGIN
                                        PRE:=PRE+A[I];
                                        INC(I);
                                END
                        ELSE
                                BEGIN
                                        PRE:=0;
                                        DEC(TOT);
                                        IF TOT=0 THEN EXIT(FALSE);
                                END;
                END;
        EXIT(TRUE);
 END;
PROCEDURE GETWAYS(P:LONGINT);
 VAR
        PRE,I,TOT:LONGINT;
 BEGIN
        TOT:=0;
        PRE:=0;
        I:=N;
        WHILE I>=1 DO
                BEGIN
                        IF (PRE+A[I]<=P)AND(M-TOT<=I) THEN
                                BEGIN
                                        PRE:=PRE+A[I];
                                        DEC(I);
                                END
                        ELSE
                                BEGIN
                                        PRE:=0;
                                        INC(TOT);
                                        WAY[TOT]:=I;
                                        IF TOT=0 THEN EXIT;
                                END;
                END;
 END;
BEGIN
        READLN(T);
        FOR IT:=1 TO T DO
        BEGIN
        READLN(N,M);
        R:=0;L:=0;
        FOR I:=1 TO N DO
                BEGIN
                        READ(A[I]);
                        R:=R+A[I];
                END;
        WHILE L<R DO
                BEGIN
                        MID:=(L+R)>>1;
                        IF CHECK(MID) THEN R:=MID ELSE L:=MID+1;
                END;
        //WRITELN(L);
        GETWAYS(L);
        L:=1;
        FOR I:=M-1 DOWNTO 1 DO
                BEGIN
                        R:=WAY[I];
                        FOR J:=L TO R DO WRITE(A[J],' ');WRITE('/ ');
                        L:=R+1;
                END;
        FOR I:=L TO N DO WRITE(A[I],' ');WRITELN;
        END;
END.

转载于:https://www.cnblogs.com/FreeDestiny/archive/2011/10/29/2228336.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值