Description
Input
Output
只有一个数字,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值。
Sample Input
4 10
1 2 3 4
1 2 3 4
1 2 3 4
Sample Output
29
HINT
输入的原图是左图,它的访问代价是1×1+2×2+3×3+4×4=30。最佳的修改方案是把输入中的第3个结点的权值改成0,得到右图,访问代价是1×2+2×3+3×1+4×2=19,加上额外修改代价10,一共是29。
感觉莫名其妙的A了
我设的状态是f[l,r,k]表示区间[l,r]的元素权值都大于等于k时的最小访问代价之和
然后枚举某个点作为根
1.这个点的权值<k,那么就花费K改成k,f[l,r,k]=min(f[l,r,k],f[l,x-1,k]+f[x+1,r,k]+s[l,r]+K)
2.这个点权值>=k,那么我们可以不花费,也可以花费K改成k,f[l,r,k]=min(f[l,r,k],f[l,x-1,k]+f[x+1,r,k]+s[l,r]+K,f[l,x-1,v[x]]+f[x+1,r,v[x]]+s[l,r])
1 const 2 maxn=75; 3 type 4 node=record 5 x,v,c:longint; 6 flag:boolean; 7 end; 8 var 9 f:array[0..maxn,0..maxn,0..maxn]of longint; 10 a:array[0..maxn]of node; 11 s:array[0..maxn]of longint; 12 n,p,ans:longint; 13 14 procedure swap(var x,y:node); 15 var 16 t:node; 17 begin 18 t:=x;x:=y;y:=t; 19 end; 20 21 procedure down(var x:longint;y:longint); 22 begin 23 if x>y then x:=y; 24 end; 25 26 procedure init; 27 var 28 i,j,cnt,min:longint; 29 begin 30 read(n,p); 31 for i:=1 to n do read(a[i].x); 32 for i:=1 to n do read(a[i].v); 33 for i:=1 to n do read(a[i].c); 34 for i:=n downto 2 do 35 for j:=1 to i-1 do 36 if a[j].x>a[j+1].x then swap(a[j],a[j+1]); 37 for i:=1 to n do s[i]:=s[i-1]+a[i].c; 38 cnt:=0;j:=1; 39 while cnt<n do 40 begin 41 min:=maxlongint; 42 for i:=1 to n do 43 if a[i].flag=false then down(min,a[i].v); 44 for i:=1 to n do 45 if (a[i].flag=false) and (a[i].v=min) then 46 begin 47 inc(cnt); 48 a[i].flag:=true; 49 a[i].v:=j; 50 end; 51 inc(j); 52 end; 53 end; 54 55 procedure dp; 56 var 57 i,j,k,l:longint; 58 begin 59 for i:=0 to n-1 do 60 for j:=1 to n-i do 61 for k:=1 to n do 62 begin 63 f[j,i+j,k]:=maxlongint; 64 for l:=j to i+j do 65 begin 66 if a[l].v<k then down(f[j,i+j,k],f[j,l-1,k]+f[l+1,i+j,k]+s[i+j]-s[j-1]+p) 67 else 68 begin 69 down(f[j,i+j,k],f[j,l-1,k]+f[l+1,i+j,k]+s[i+j]-s[j-1]+p); 70 down(f[j,i+j,k],f[j,l-1,a[l].v]+f[l+1,i+j,a[l].v]+s[i+j]-s[j-1]); 71 end; 72 end; 73 end; 74 ans:=maxlongint; 75 for i:=1 to n do down(ans,f[1,n,i]); 76 writeln(ans); 77 end; 78 79 begin 80 init; 81 dp; 82 end.