## bzoj 1044 贪心二分+DP

w[j,i]:=sigma(w[j-1,k]) sum[i]-sum[k-1]<=ans

/**************************************************************
Problem: 1044
Language: Pascal
Result: Accepted
Time:2040 ms
Memory:1208 kb
****************************************************************/

var
w                           :array[0..1,-3..50000] of longint;
pre, a, s                   :array[-1..50000] of longint;
last                        :array[-1..1001] of longint;
p, ans2, tot                :longint;
max, tmp                    :longint;
i, j, h, k                  :longint;
l, r, mid, ans              :longint;
n, m                        :longint;

function check(x:longint):boolean;
var i                           :longint;
begin
if max>x then exit(false);
tmp:=0;
tot:=0;
for i:=1 to n do
begin
if tmp+a[i]<=x then tmp:=tmp+a[i]
else begin
tmp:=a[i];
inc(tot);
if tot>m then exit(false);
end;
end;
exit(true);
end;

begin
if n=0 then
begin
writeln(0,' ',1);
exit;
end;
for i:=1 to n do
begin
s[i]:=s[i-1]+a[i];
if max<a[i] then max:=a[i];
end;
l:=1;
r:=s[n];
while l<r do
begin
if l=r-1 then
begin
if check(l) then ans:=l
else ans:=r;
break;
end;
mid:=(l+r) shr 1;
if check(mid) then r:=mid else l:=mid;
end;

tmp:=0;
tot:=0;
for i:=1 to n do
begin
if tmp+a[i]>ans then
begin
tmp:=a[i];
inc(tot);
last[tot]:=i-1;
end else tmp:=tmp+a[i];
end;
for i:=tot+1 to m+1 do last[i]:=n;
h:=1;
for i:=1 to n do
begin
while s[i]-s[h]>ans do inc(h);
pre[i]:=h;
end;

for i:=1 to last[1] do w[1,i]:=w[1,i-1]+1;
for i:=last[1]+1 to last[2] do w[1,i]:=w[1,i-1];
l:=1;
for i:=2 to m+1 do
begin
k:=l;
l:=k xor 1;
w[l,i]:=1;
p:=1;
for j:=i+1 to last[i] do
begin
p:=w[k,j-1]-w[k,pre[j]-1];
w[l,j]:=(w[l,j-1]+p) mod 10007;
end;
if last[i]=n then ans2:=(ans2+p) mod 10007
else begin
for j:=last[i]+1 to last[i+1] do w[l,j]:=w[l,j-1];
end;
end;
writeln(ans,' ',(ans2 mod 10007+10007) mod 10007);
end.

posted on 2013-11-21 17:21  BLADEVIL  阅读(269)  评论(0编辑  收藏