嗯,这是一道简单题

注意二叉搜索树的子树中序一定是连续的

又因为取值修改是任意的并且修改代价与权值无关

不难想到把权值离散化,然后按找数据值排序,然后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.
View Code

 

posted on 2015-06-30 16:22  acphile  阅读(131)  评论(0编辑  收藏  举报