P<=10一开始是吓死我了

后来想到这就是一个经典的决策单调性解决1d1d动态规划的题目

像决策单调性完全可以打表找规律,这里有一篇严谨的证明https://www.byvoid.com/blog/noi-2009-poet

关于1d1d动归的优化可以看《1d1d动态规划优化初步》

注意可能会爆longlong,所以用extended计算

 type node=record
l,r,x:longint;
end; var q:array[..] of node;
f:array[..] of extended;
s:array[..] of longint;
x,h,r,i,n,l,p,tt:longint;
ss:string; function pow(x:extended):extended;
var i:longint;
begin
pow:=;
for i:= to p do
pow:=pow*x;
end; function calc(j,i:longint):extended;
begin
exit(f[j]+pow(abs(s[i]-s[j]+i-j--l)));
end; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure update(i:longint);
var l,t,m,ans:longint;
begin
if calc(i,n)>calc(q[r].x,n) then exit;
while (i<q[r].l) and (calc(i,q[r].l)<calc(q[r].x,q[r].l)) do dec(r); l:=max(i+,q[r].l);
t:=q[r].r;
ans:=min(n,q[r].r+);
while l<=t do
begin
m:=(l+t) shr ;
if calc(i,m)<calc(q[r].x,m) then
begin
ans:=m;
t:=m-;
end
else l:=m+;
end;
q[r].r:=ans-;
inc(r);
q[r].x:=i;
q[r].l:=ans;
q[r].r:=n;
end; begin
readln(tt);
while tt> do
begin
dec(tt);
readln(n,l,p);
s[]:=;
for i:= to n do
begin
readln(ss);
x:=length(ss);
s[i]:=s[i-]+x;
end;
h:=;
r:=;
q[].x:=;
q[].l:=;
q[].r:=n;
for i:= to n do
begin
while i>q[h].r do inc(h);
f[i]:=calc(q[h].x,i);
update(i);
end;
if f[i]<=1e18 then writeln(trunc(f[i])) //注意这里trunc不能0:
else writeln('Too hard to arrange');
writeln('--------------------');
end;
end.
05-11 17:22