• P3874 [TJOI2010]砍树


    典型的树形DP,但是做起来还是要看题解,看来还是不会吖.

    题目背景

    (A)在果园里发现了一棵结满果子的树,于是他就打起了坏主意,他打算把树的一部分砍下来带回家。

    题目描述

    我们可以把这棵树表示成一个树型的结构,也就是说,任意两个点之间有且仅有一条路径。在每个点(i)处都结着一个水果,每个水果有一个价值(v_i)和重量(w_i)。小(A)想带走树的一部分(或全部),包含至少(K)个结点(也就是至少(K)个水果),且这些水果的平均价值尽可能高。平均价值是指水果总的价值除以总的重量。注意小(A)砍下的树必须是在原来的树中连通的一部分。

    输入格式

    第一行包含两个数(N)(K),分别表示树的结点数和小(A)至少应带走的水果数。第二行包含空格隔开的(N)个数,分别表示每个结点处水果的价值(v_i)。第三行包含空格隔开的(N)个数,分别表示每个水果的重量(w_i)。按下来(N-1)行,每行包含两个数(a_i)(b_i)(1 ≤ a_i, b_i ≤ N)),表示在结点(a_i)(b_i)之间有一条边。输入保证是一棵正确的树结构。

    输出格式

    输出一行,包含一个数,表示最大可能的平均价值。四舍五入到小数点后两位。

    数据范围

    (100%)的数据,(1 ≤ N ≤ 100, 1 ≤ K ≤ N, 1 ≤ v_i ≤ 10000, 1 ≤ w_i ≤ 10000)

    解析

    看到价值和重量,就知道这是一道我不会的树上背包问题.一般背包可以设(f_{i})表示选择重量不超过(j)的物品能获得的最大价值,但是这道题要结合树形结构,而且(w)(v)的范围都很大,所以考虑基于个数来设置状态.

    我们设(f_{i,j})表示在以(i)为根的子树中选择(j)个点能获得的最大平均价值.对于它的每棵子树,我们枚举从中选择了多少节点来转移.

    ※因为题目要求记录平均值,而平均值并不容易直接转移,所以我们将(f)数组开成结构体,记录当前状态的总重量,总价值,以及平均值(总价值/总重量).这道题显然是树上(01)背包,因此别忘了要倒序循环外层.

    struct node {
        double w, v, ave;//重量,权值,平均值
        node() {}
        node(double a, double b, double c) : w(a), v(b), ave(c) {}
    }f[105][105];
    
    void dfs(int now, int father) {
        f[now][1] = node(w[now], v[now], v[now] / w[now]);//为了维护连通性,根节点肯定要选.
        for (int i = head[now]; i; i = nxt[i]) {
            if (to[i] == father)//枚举每个子节点
                continue;
            dfs(to[i], now);//先递归下去,再由叶到根更新
            for (int j = n; j > 1; --j) {//枚举以now为根的子树中一共选择多少个点,注意01背包要倒序
                for (int k = 1; k <= j; ++k) {//枚举当前子树中选择了j个节点中的多少个
                    node p = f[to[i]][j - k];//在这个子树中选择了j个节点中的j-k个点
                    node q = f[now][k];//在其他子树中选择了k个点.
                    double ave = (p.v + q.v) / (p.w + q.w);//计算平均值
                    if (ave >= f[now][j].ave) {//更新答案
                        f[now][j] = node(p.w + q.w, p.v + q.v, ave);
                    }
                }
            }
        }
        return;
    }
    

    最后在所有(f[i][j](k le j le n))中选择最大值输出即可.

    感觉还是不会呢

  • 相关阅读:
    SSH Config 那些你所知道和不知道的事 (转)
    解决npm ERR! Unexpected end of JSON input while parsing near的方法
    ES查询-term VS match (转)
    ES查询-match VS match_phrase
    安装使用aria2下载百度网盘内容(转)
    基于CSS3鼠标滑过放大突出效果
    基于jQuery的新浪游戏首页幻灯片
    基于animation.css实现动画旋转特效
    基于jQuery左右滑动切换特效
    基于html5顶部导航3D翻转展开特效
  • 原文地址:https://www.cnblogs.com/i-cookie/p/11434173.html
Copyright © 2020-2023  润新知