您的位置:首页 > 其它

BZOJ 1564: [NOI2009]二叉查找树( dp )

2016-02-13 21:54 369 查看


树的中序遍历是唯一的. 按照数据值处理出中序遍历后, dp(l, r, v)表示[l, r]组成的树, 树的所有节点的权值≥v的最小代价(离散化权值).

枚举m为根(p表示访问频率):

修改m的权值 : dp(l, r, v) = min( dp(l, m-1, v) + dp(m+1, r, v) + p(l~r) + K )

不修改(m原先权值≥v) : dp(l, r, v) = min( dp(l, m-1, Value(m)) + dp(m+1, r, Value(m)) + p(l~r) )

时间复杂度O( N log N + N^4 )

-------------------------------------------------------------------------------

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm> using namespace std; typedef long long ll; const int maxn = 79;const ll inf = 1LL << 60; int N, C, H[maxn];ll dp[maxn][maxn][maxn]; template<class T>inline void Min(T &x, T t) { if(t < x) x = t;} struct Node { int d, v, p; bool operator < (const Node &o) const { return d < o.d; }} o[maxn]; ll Dp(int l, int r, int v) { if(l > r) return 0; ll &t = dp[l][r][v]; if(~t) return t; int d = o[r].p - o[l - 1].p; if(l == r) return t = d + (o[l].v >= v ? 0 : C); t = inf; for(int i = l; i <= r; i++) { Min(t, Dp(l, i - 1, v) + Dp(i + 1, r, v) + C + d); if(o[i].v >= v) Min(t, Dp(l, i - 1, o[i].v) + Dp(i + 1, r, o[i].v) + d); } return t;} int main() { scanf("%d%d", &N, &C); for(int i = 1; i <= N; i++) scanf("%d", &o[i].d); for(int i = 1; i <= N; i++) scanf("%d", &o[i].v); for(int i = 1; i <= N; i++) scanf("%d", &o[i].p); sort(o + 1, o + N + 1); o[0].p = 0; for(int i = 1; i <= N; i++) { o[i].p += o[i - 1].p; H[i - 1] = o[i].v; } sort(H, H + N); int hn = unique(H, H + N) - H; for(int i = 1; i <= N; i++) o[i].v = lower_bound(H, H + hn, o[i].v) - H; memset(dp, -1, sizeof dp); ll ans = inf; for(int i = 0; i < hn; i++) Min(ans, Dp(1, N, i)); cout << ans << "\n"; return 0;}-------------------------------------------------------------------------------

1564: [NOI2009]二叉查找树

Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 625 Solved: 453
[Submit][Status][Discuss]

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。



Source

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: