[codevs2467]午餐 排序+dp+部分贪心

首先对所有的人按照B[I]降序排列、

F[I,J]表示在第I个人、在第一个窗口花费J时间打饭、 I个人吃饭所需要的最小值

楼主dp真的很弱~~~写了好多遍也没对,最后发现初值付错2333

一定要注意,dp中除了f[0][0]外全部付成max(当然不要127容易爆,125足矣);

贴上代码,感觉容易多了

const maxn=233;
var i,j,n,ans:longint;
    a,b:array[0..maxn] of longint;
    s:array[0..maxn] of longint;
    f:array[0..maxn,0..maxn*maxn] of longint;
function min(a,b:longint):longint;
begin
        if a<b then exit(a) else exit(b);
end;
function max(a,b:longint):longint;
begin
        if a>b then exit(a) else exit(b);
end;
procedure swap(var a,b:integer);
var t:longint;
begin
        t:=a; a:=b; b:=t;
end;
procedure qsort(l,r: longint);
var i,j,x:longint;
        begin
                i:=l;
                j:=r;
                x:=b[(l+r) div 2];
                repeat
                        while b[i]>x do inc(i);
                        while x>b[j] do dec(j);
                        if not(i>j) then
                        begin
                                swap(a[i],a[j]);
                                swap(b[i],b[j]);
                                inc(i);
                                j:=j-1;
                        end;
                until i>j;
                if l<j then qsort(l,j);
                if i<r then qsort(i,r);
end;
begin
        readln(n);
        for i:=1 to n do
                readln(a[i],b[i]);
        qsort(1,n);
        for i:=1 to n do
                s[i]:=s[i-1]+a[i];
        fillchar(f,sizeof(f),125);
        f[0,0]:=0;
        for i:=1 to n do
        for j:=0 to s[i] do
        begin
                if j>=a[i] then
                f[i,j]:=min(f[i,j],
                        max(max(j+b[i],f[i-1,j-a[i]]),s[i]-j));
                f[i,j]:=min(f[i,j],max(max(f[i-1,j],s[i]-j+b[i]),j));
        end;
        ans:=maxlongint;
        for i:=0 to s[n] do ans:=min(ans,f[n,i]);
        writeln(ans);
end.

 

 喜欢就收藏一下,vic私人qq:1064864324,加我一起讨论问题,一起进步^-^

posted @ 2015-09-28 08:08  ROLL-THE-FIRST  阅读(147)  评论(0编辑  收藏  举报