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 MBSubmit: 625 Solved: 453
[Submit][Status][Discuss]
Description
Input
Output
只有一个数字,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值。Sample Input
4 101 2 3 4
1 2 3 4
1 2 3 4
Sample Output
29HINT
输入的原图是左图,它的访问代价是1×1+2×2+3×3+4×4=30。最佳的修改方案是把输入中的第3个结点的权值改成0,得到右图,访问代价是1×2+2×3+3×1+4×2=19,加上额外修改代价10,一共是29。Source
相关文章推荐
- 第二十二天
- Arrays类的十大用法
- poj2195
- Android Wear 进阶 - 4 发送和同步数据 <Sending and Syncing Data>
- ubuntu没有man pthread_mutex_init
- POJ2184(01背包变形)
- 安装 Ubuntu 后的个人常用配置
- mysql-5.6.27主从设置
- 关于隐藏Windows控制台的办法
- java设计模式系列之装饰者模式
- AndroidStudio怎样导入jar包
- 自定义UICollectinviewFlowLayout,即实现瀑布流
- 网站模板的应用
- linux--ubuntu下Vim安装失败
- 【BZOJ 2440】[中山市选2011]完全平方数
- 【深度学习】初次接触
- NEU 2016年2月月赛总结
- POJ 2774 Long Long Message
- linux 安装 killall命令
- Nginx之location 匹配规则详解