"The main topic"

The key values, weights, and access frequencies for each node on a treap are known. It is now possible to modify the weights of some nodes (which can be modified to real numbers) and to pay the extra cost of K (k for customization). The total cost of a treap =∑ (the access frequency * depth per node) + additional cost.

* Interesting conclusion: When the key value and weight are determined, the treap is the only certainty.

Ideas

First, the key value is not changed, we sort by the key value, that is, by the middle order traversal sort. F[I][J][W] Represents a subtree of i~j and the weights of each point are greater than or equal to the minimum total cost of W.

Enumeration interval I, j as the root of K. If wk>=w, you can not change root, Fi[l][r][k]=min (Fi[l][i-1][wk]+fi[i+1][r][wk]+sm[l~i-1]+sm[i+1~r]), you can also change the root, fi[l][r][k]= Min (Fi[l][i-1][k]+fi[i+1][r][k]+kk+sm[l~i-1]+sm[i+1~r]).

Notice that at first my idea was that "f[i][j][w" represents a subtree of i~j and that the weights of each point are greater than the minimum total cost of w ", but I do not see that it can be modified to a **real** number, so it can only be used greater than equals.

* Focus on the initial values and order of the DP, which is described in detail in the code comments.

1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5#include <cmath>6#include <vector>7 using namespacestd;8 Const intmaxn= -+5;9 Const intinf=0x7fffffff;Ten structnode One { A intdata,weight,frequency; - BOOL operator< (Constnode& x)Const - { the returndata<X.data; - } - }A[MAXN]; - intN,K,HASH[MAXN]; + intF[MAXN][MAXN][MAXN];//F[i][j][w] A subtree of i~j and the weight of each point is greater than or equal to the minimum total cost of W - + voidInit () A { atscanf"%d%d",&n,&K); - for(intI=1; i<=n;i++) scanf ("%d",&a[i].data); - for(intI=1; i<=n;i++) scanf ("%d", &a[i].weight), hash[i]=A[i].weight; - for(intI=1; i<=n;i++) scanf ("%d",&a[i].frequency); - -Sort (hash+1, hash+n+1); inSort (A +1, a+n+1); - intD=unique (hash+1, hash+n+1)-(hash+1); to for(intI=1; i<=n;i++) + { -A[i].weight=lower_bound (hash+1, hash+d+1, A[i].weight)-Hash; the } * for(intI=2; i<=n;i++) $a[i].frequency+=a[i-1].frequency;//find the prefix andPanax Notoginseng - } the + voidDP () A { theMemset (F,0x3f,sizeof(f)); + for(intI=1; i<=n+1; i++) - for(intw=0; w<=n;w++) f[i][i-1][w]=0; $ //This initialization takes note (!), which is used at the bottom (i=k/j=k) $ for(intw=n;w;w--)//according to the transfer conditions, obviously W is bigger than the ball first, so from big to small, put in the outermost loop - for(inti=n;i;i--) - for(intj=i;j<=n;j++) the for(intk=i;k<=j;k++) - {Wuyi if(a[k].weight>=w) F[i][j][w]=min (f[i][j][w],f[i][k-1][a[k].weight]+f[k+1][j][a[k].weight]+ (a[j].frequency-a[i-1].frequency)); the //Since the root node is added, the depth of each node is +1, so add the frequency of access and - //because the real number can be taken, so the back a[k].weight does not need +1, the following w is also the same WuF[i][j][w]=min (f[i][j][w],f[i][k-1][w]+f[k+1][j][w]+ (a[j].frequency+k-a[i-1].frequency)); - } About intans=INF; $ for(intI=0; i<=n;i++) -Ans=min (ans,f[1][n][i]); -printf"%d", ans); - } A + intMain () the { - init (); $ DP (); the return 0; the}

"DP" bzoj1564-[NOI2009] binary search tree (!!)