嗯,这是一道简单题
注意二叉搜索树的子树中序一定是连续的
又因为取值修改是任意的并且修改代价与权值无关
不难想到把权值离散化,然后按找数据值排序,然后dp
f[i][j][w]表示从i~j的节点构成一棵子树且所有节点权值都大于等于w的最小代价和
转移很明显,记忆化搜索即可
1 const inf=2147483647; 2 3 var f:array[0..75,0..75,0..75] of longint; 4 s,a,b,c,d,p:array[0..75] of longint; 5 i,n,m,k:longint; 6 7 procedure min(var a:longint; b:longint); 8 begin 9 if a>b then a:=b; 10 end; 11 12 procedure swap(var a,b:longint); 13 var c:longint; 14 begin 15 c:=a; 16 a:=b; 17 b:=c; 18 end; 19 20 procedure sort1(l,r:longint); 21 var i,j,x:longint; 22 begin 23 i:=l; 24 j:=r; 25 x:=b[(l+r) shr 1]; 26 repeat 27 while b[i]<x do inc(i); 28 while x<b[j] do dec(j); 29 if not(i>j) then 30 begin 31 swap(b[i],b[j]); 32 swap(d[i],d[j]); 33 inc(i); 34 dec(j); 35 end; 36 until i>j; 37 if l<j then sort1(l,j); 38 if i<r then sort1(i,r); 39 end; 40 41 procedure sort2(l,r:longint); 42 var i,j,x:longint; 43 begin 44 i:=l; 45 j:=r; 46 x:=a[(l+r) shr 1]; 47 repeat 48 while a[i]<x do inc(i); 49 while x<a[j] do dec(j); 50 if not(i>j) then 51 begin 52 swap(a[i],a[j]); 53 swap(c[i],c[j]); 54 swap(p[i],p[j]); 55 inc(i); 56 dec(j); 57 end; 58 until i>j; 59 if l<j then sort2(l,j); 60 if i<r then sort2(i,r); 61 end; 62 63 function dp(l,r,m:longint):longint; 64 var i:longint; 65 begin 66 if l>r then exit(0); 67 if f[l,r,m]<>-1 then exit(f[l,r,m]); 68 f[l,r,m]:=inf; 69 for i:=l to r do 70 begin 71 min(f[l,r,m],dp(l,i-1,m)+dp(i+1,r,m)+k); 72 if p[i]>=m then 73 min(f[l,r,m],dp(l,i-1,p[i]+1)+dp(i+1,r,p[i]+1)); 74 end; 75 f[l,r,m]:=f[l,r,m]+s[r]-s[l-1]; 76 exit(f[l,r,m]); 77 end; 78 79 begin 80 readln(n,k); 81 for i:=1 to n do 82 begin 83 read(a[i]); 84 d[i]:=i; 85 end; 86 for i:=1 to n do 87 read(b[i]); 88 for i:=1 to n do 89 read(c[i]); 90 sort1(1,n); 91 m:=1; 92 p[d[1]]:=1; 93 for i:=2 to n do 94 begin 95 if b[i]<>b[i-1] then inc(m); 96 p[d[i]]:=m; 97 end; 98 sort2(1,n); 99 for i:=1 to n do 100 s[i]:=s[i-1]+c[i]; 101 fillchar(f,sizeof(f),255); 102 writeln(dp(1,n,1)); 103 end.