bzoj1564: [NOI2009]二叉查找树

dp。

首先这棵树是一个treap。

权值我们可以改成任意实数,所以权值只表示相互之间的大小关系,可以离散化。

树的中序遍历是肯定确定的。

用f[l][r][w]表示中序遍历为l到r,根的权值必须大于w的最小代价。

当a[x].w<=w时有f[l][r][w]=min(f[l][x-1][w]+f[x+1][r][w]+s[l][r]+k).s[i][j]表示从l到r访问次数的和。

当a[x].w>w时,还有f[l][r][w]=min(f[l][x-1][w]+f[x+1][r][w]+s[l][r]).不用修改了。

对于[1,n]来说,根的权值只存在改和不改俩种状态。所以res=min(f[1][n][0],f[1][n][1])。

必须是这俩个取min,如果只取0的话,就会忽略根为原树的根的答案。

否则就会忽略根不为原树的答案(这不是废话么。。其实因为新根能改为小于1,如果只能改为1的话,原根的权值还要变大)。

用一个res作为引用可以不用打那么一长串(膜lrj巨神)

#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
const int maxn = 70 + 10;
const LL inf = 0x3f3f3f3f3f3f3f3fll;

struct Point {
    int v,w,d;
}a[maxn];
int n,k;
LL f[maxn][maxn][maxn],s[maxn],res;

bool cmp1(Point p1,Point p2) {
    return p1.w<p2.w;
}

bool cmp2(Point p1,Point p2) {
    return p1.v<p2.v;
}

LL DP(int l,int r,int w) {
    if(l>r) return 0;
    if(f[l][r][w]!=inf) return f[l][r][w];

    for(int x=l;x<=r;x++) {
        LL& res=f[l][r][w];
        res=min(res,DP(l,x-1,w)+DP(x+1,r,w)+s[r]-s[l-1]+k);
        if(a[x].w>w)
        res=min(res,DP(l,x-1,a[x].w)+DP(x+1,r,a[x].w)+s[r]-s[l-1]);
    }
    return f[l][r][w];
}

int main() {
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].v);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].w);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].d);
    sort(a+1,a+n+1,cmp1);
    for(int i=1;i<=n;i++) a[i].w=i;
    sort(a+1,a+n+1,cmp2);
    for(int i=1;i<=n;i++) {
        a[i].v=i;
        s[i]=s[i-1]+a[i].d;
    }
    memset(f,0x3f,sizeof(f));
    printf("%lld\n",min(DP(1,n,0),DP(1,n,1)));
    return 0;
}
时间: 2024-08-01 20:17:11

bzoj1564: [NOI2009]二叉查找树的相关文章

[BZOJ1564][NOI2009]二叉查找树(区间DP)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1564 分析: 首先因为每个点的数据值不变,所以无论树的形态如何变,树的中序遍历肯定不变,就是所有数据值从小到大排. 然后设f[i][j][v]表示中序遍历的i~j位组成一颗子树,其中要求权值都>=v的最小花费 枚举k作为树根(i<=k<=j) 则两种情况: 若k的权值<v,则f[i][j][v]=min(f[i][k-1][v]+f[k+1][j][v]+额外费用+i~

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

树的中序遍历是唯一的. 按照数据值处理出中序遍历后, 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~

NOI2009 二叉查找树 【区间dp】

[NOI2009]二叉查找树 [问题描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左子树结点的数据值大,而比它右子树结点的数据值小.另一方面,这棵查找树中每个结点都有一个权值,每个结点的权值都比它的儿子结点的权值要小.已知树中所有结点的数据值各不相同:所有结点的权值也各不相同.这时可得出这样一个有趣的结论:如果能够确定树中每个结点的数据值和权值,那么树的形态便可以唯一确定.因为这样的一棵树可以看成是按照权值从小到大顺序插入结点所得到的.按照数据值排序的二叉查找树

bzoj 1564 [NOI2009]二叉查找树(树形DP)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1564 [题意] 给定一个Treap,总代价为深度*距离之和.可以每次以K的代价修改权值,问最小代价. [思路] 数据值是不变的,因此Treap的中序遍历是唯一的.先将数据按照数据值排序,得到其中序遍历. 然后将权值离散化到[1,n]区间内. 设f[l][r][w]为区间[l,r]内的权值都比w大时的最小代价,则有转移式: f[l][r][w]=min { f[l][k-1][w]+f

1564: [NOI2009]二叉查找树 - BZOJ

Description Input Output只有一个数字,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值.Sample Input4 101 2 3 41 2 3 41 2 3 4Sample Output29HINT输入的原图是左图,它的访问代价是1×1+2×2+3×3+4×4=30.最佳的修改方案是把输入中的第3个结点的权值改成0,得到右图,访问代价是1×2+2×3+3×1+4×2=19,加上额外修改代价10,一共是29. 感觉莫名其妙的A了 我设的状态是f[l,r,k]表示区

YCB 的暑期计划

前言 YCB现在很弱(TAT) 暑假有一个月,赶快狂补一下. 大概的计划如下: 首先前期会以数据结构为主,毕竟代码能力太弱,涉及内容:线段树分治.二进制分组.KD-Tree. 等数据结构做到没有智商的时候加入一波数论,内容为 杜教筛.min_25筛. 然后中途小清新一下,做一些 组合博弈与构造题. 接着继续练代码能力,顺便学一些神奇的暴力:启发式合并.dsu on tree . 然后图论也忘的差不多了,就回过头去学点新东西,大概会有spfa判负环.0/1分数规划.差分约束. 估计这个时候也没有什

【树型DP】BZOJ1564 二叉查找树(noi2009)

二叉查找树 [题目描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小. 另一方面,这棵查找树中每个结点都有一个权值,每个结点的权值都比它的儿子结点的权值要小. 已知树中所有结点的数据值各不相同:所有结点的权值也各不相同.这时可得出这样一个有趣的结论:如果能够确定树中每个结点的数据值和权值,那么树的形态便可以唯一确定.因为这样的一棵树可以看成是按照权值从小到大顺序插入结点所得到的.按照数据值排序的二叉查找树. 一个结点在

bzoj1564 二叉查找树

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 http://www

【NOI2009】植物大战僵尸

P1589 - [NOI2009]植物大战僵尸 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而 Zombies进攻.该款游戏包含多种不同的挑战系列,比如Protect Your Brain.Bowling等等.其中最为经典的,莫过于玩家通过控制Plants来防守Zombies的进攻,或者相反地由玩家通过控制Zombies 对Plants发起进攻. 现在,我们将要考