1564: [NOI2009]二叉查找树 区间DP
来源:互联网 发布:淘宝6.5.0版本下载 编辑:程序博客网 时间:2024/06/08 18:27
DP太弱了。。不会做T T
这题的条件非常多也非常乱,所以我们要先挖掘一些性质,尽量的找到一个解决问题的顺序。可以发现所谓的数据值和权值其实就是一棵treap,改变权值相当于treap的旋转,由于数据值不变,所以中序遍历是不变的,所以我们可以按数据值排序,得到树的中序遍历。并且我们发现权值可以取所有实数,而且权值的大小与最后的答案无关,所以可以离散权值到
然后我们考虑用
若
或者可以直接把
其中
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#define N 100using namespace std;struct node {int x,y,z;} a[N];pair<int,int> b[N];int f[N][N][N];int n,K;inline int read(){ int a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f;}inline bool cmp(node a,node b){ return a.x<b.x;}int main(){ n=read(); K=read(); for (int i=1;i<=n;i++) a[i].x=read(); for (int i=1;i<=n;i++) a[i].y=read(); for (int i=1;i<=n;i++) a[i].z=read(); sort(a+1,a+n+1,cmp); for (int i=1;i<=n;i++) b[i]=make_pair(a[i].y,i); sort(b+1,b+n+1); for (int i=1;i<=n;i++) a[b[i].second].y=i; for (int i=1;i<=n;i++) a[i].z+=a[i-1].z; memset(f,0x3f,sizeof(f)); for (int i=1;i<=n+1;i++) for (int w=0;w<=n;w++) f[i][i-1][w]=0; for (int w=n;~w;w--) for (int i=n;i;i--) for (int j=i;j<=n;j++) for (int k=i;k<=j;k++) { if (a[k].y>=w) f[i][j][w]=min(f[i][j][w],f[i][k-1][a[k].y]+f[k+1][j][a[k].y]+a[j].z-a[i-1].z); f[i][j][w]=min(f[i][j][w],f[i][k-1][w]+f[k+1][j][w]+K+a[j].z-a[i-1].z); } cout << f[1][n][0] << endl; return 0;}
0 0
- 1564: [NOI2009]二叉查找树 区间DP
- 【BZOJ1564】[NOI2009]二叉查找树【区间DP】
- 【树型DP】BZOJ1564 二叉查找树(noi2009)
- 【BZOJ】1564: [NOI2009]二叉查找树
- [bzoj1564][NOI2009]二叉查找树
- bzoj1564: [NOI2009]二叉查找树
- BZOJ 1564 NOI2009 二叉查找树 动态规划
- 【动态规划】【NOI2009】二叉查找树
- [BZOJ1564][NOI2009]二叉查找树 动态规划
- 二叉查找树搜索区间
- 加分二叉树 区间dp
- 题目:二叉查找树中搜索区间
- 二叉查找树中搜索区间
- 二叉查找树中搜索区间
- 二叉查找树中搜索区间
- Lintcode 二叉查找树中搜索区间
- 二叉查找树中搜索区间
- lintcode-二叉树中查找区间
- 创建线程的方式(继承和实现接口两种)
- jdk1.5~1.8特性
- Tomcat 优化方案(转)
- 进程/线程同步的方式和机制,进程间通信
- Cnki数据集包装清洗
- 1564: [NOI2009]二叉查找树 区间DP
- 浏览器禁止 后退键
- activity界面学习
- MPU6050 实时图表上位机 C#
- 设计模式-6大设计原则
- adb命令
- 算法训练 最大体积
- navicat 1045 access denied for user
- dispatch_async 和dispatch_sync GCD