这两题都是某一个很神的一个论文里(留邮箱。。我发)写的第一种模型
HDU 3507
F[I]:=MIN{F[J]+W[J+1,I]}(1<=J<I)中的
我们可以打表观察决策然后来确定满不满足决策单调性。
决策单调性就是:假设G[I]为i的决策位置
那么G[I]<=G[J](i<j)一定满足
所以可以把O(N^2)的DP优化到O(NLOGN)
code:(注意 continue)
BZOJ 1010
var
l,r,c:array[0..50005] of longint;
a,sum,f:array[0..50005] of int64;
t1,m:int64;
i,n,h,t,head,tail,mid:longint;
function work(i,j,k:longint):boolean;
var
t1,t2:int64;
begin
t1:=(sum[i]-sum[j]-m+(i-j-1))*(sum[i]-sum[j]-m+(i-j-1))+f[j];
t2:=(sum[i]-sum[k]-m+(i-k-1))*(sum[i]-sum[k]-m+(i-k-1))+f[k];
if t1<t2 then exit(false) else exit(true);
end;
begin
fillchar(f,sizeof(f),0);
fillchar(sum,sizeof(sum),0);
read(n,m);
for i:=1 to n do
begin
read(a[i]);
sum[i]:=sum[i-1]+a[i];
end;
h:=1;t:=1;l[h]:=1;r[h]:=n;c[h]:=0;
for i:=1 to n do
begin
while r[h]<i do
h:=h+1;
t1:=sum[i]-sum[c[h]]+(i-c[h]-1)-m;
t1:=t1*t1;
f[i]:=f[c[h]]+t1;
while work(l[t],c[t],i) and (h<t) do
begin
t:=t-1;
r[t]:=r[t+1];
end;
if work(l[t],c[t],i) and (h=t) then
begin
c[h]:=i;
continue;
end;
head:=l[t];tail:=r[t];
if head<=i then head:=i+1;
while head<=tail do
begin
mid:=(head+tail) div 2;
if work(mid,c[t],i) then tail:=mid-1 else head:=mid+1;
end;
tail:=tail+1;
t:=t+1;
R[T-1]:=tail-1;
l[t]:=tail;r[t]:=n;c[t]:=i;
end;
writeln(f[n]);
end.
HDU 3507
var
n,i,h,t,head,tail,mid:longint;
f,a,sum:array[0..500005] of int64;
l,r,c:array[0..500005] of longint;
m,tmp,t1:int64;
function work(i,j,k:longint):boolean;
var
t1,t2:int64;
begin
t1:=(sum[i]-sum[j])*(sum[i]-sum[j])+f[j]+m;
t2:=(sum[i]-sum[k])*(sum[i]-sum[k])+f[k]+m;
if t2<=t1 then work:=true else work:=false;
end;
begin
assign(input,'1.in');assign(output,'1.ans');
reset(input);rewrite(output);
while not eof do begin
fillchar(f,sizeof(f),0);
fillchar(sum,sizeof(sum),0);
readln(n,m);
for i:=1 to n do
begin
readln(a[i]);
sum[i]:=sum[i-1]+a[i];
end;
h:=1;t:=1;
l[h]:=1;r[h]:=n;c[h]:=0;
for i:=1 to n do
begin
while r[h]<i do
h:=h+1;
t1:=(sum[i]-sum[c[h]]);
tmp:=t1*t1+m;
f[i]:=f[c[h]]+tmp;
while work(l[t],c[t],i) and (t>h) do
begin
t:=t-1;
r[t]:=r[t+1];
end;
if work(i+1,c[t],i) and (t=h) then
begin
c[t]:=i;
continue;
end;
head:=l[t];tail:=r[t];
if head<=i then head:=i+1;
while head<=tail do
begin
mid:=(head+tail) div 2;
if work(mid,c[t],i) then tail:=mid-1 else head:=mid+1;
end;
tail:=tail+1;
t:=t+1;
r[t-1]:=tail-1;
l[t]:=tail;r[t]:=n;c[t]:=i;
end;
writeln(f[n]);end;close(input);close(output);
end.

本文介绍了一种通过利用决策单调性将动态规划的时间复杂度从O(N^2)优化到O(NlogN)的方法,并提供了两个具体的实现案例。
2828

被折叠的 条评论
为什么被折叠?



