前置

树形 dp,二分。

题意

本质上是一个树上背包,需要选不少于 \(k\) 个物品,每个物品有一个重量 \(w\) 和价值 \(v\),求性价比最大值。

分析

既然是性价比,显然是分数规划。

先介绍一下分数规划是什么:

我们二分这个最大性价比。

假设当前枚举到 \(mid\),则我们将每个点的价值修改为

\[v-mid \times w
\]

然后我们正常做树形 dp,然后统计一下是否有价值大于等于 \(0\) 的即可。

那么为什么这样呢?

假设性价比为 \(g\),我们选的是

\[p_1,p_2,...p_s( k\le s \le n)
\]

则我们有

\[\frac {\sum_{i=1}^s{v_{p_i}}}{\sum_{i=1}^s{w_{p_i}}}=g
\]

进而可以推出

\[\sum_{i=1}^s{w_{p_i} \times g}=\sum_{i=1}^s{v_{p_i}}
\]

那么,当我们定义价值 \(val_i=v_i-w_i \times g\) 时,有

\[\sum_{i=1}^s{val_{p_i}}=0\ge0
\]

成立,故以上算法正确。

实现

比较好说,先二分出来 \(g\),然后跑树形背包即可,注意要一边计算大小 \(size_p\) 一边跑背包,不然复杂度 \(O(n^3)\),加上二分可能 TLE。(虽然我没试过)

然后就是注意把精度卡到 \(0.0001\),不然会 WA。

Code

#include <bits/stdc++.h>

using namespace std;

const int N = 110;
typedef double db; int ver[N * 2], nxt[N * 2], hd[N], idx; inline void add (int x, int y) {
ver[++idx] = y;
nxt[idx] = hd[x];
hd[x] = idx;
} int n, w[N], v[N], k, s[N];
bool mk[N];
db dp[N][N], g[N]; void dfs (int u, int fa) {
dp[u][0] = 0; dp[u][1] = g[u]; s[u] = 1;
for (int i = hd[u]; i ;i = nxt[i]) {
int y = ver[i];
if (y == fa) continue;
dfs(y, u);
s[u] += s[y]; //注意size和dp要一起算
for (int j = min(n, s[u]);j >= 1;j--) { //处理背包
for (int z = 0;z <= min(j - 1, s[y]);z++) {
dp[u][j] = max(dp[u][j], dp[u][j - z] + dp[y][z]);
}
}
}
} bool check (db x) {
for (int i = 1;i <= n;i++) g[i] = v[i] - x * w[i]; //处理val
for (int i = 1;i <= n;i++) for (int j = 0;j <= n;j++) dp[i][j] = -200000;
dfs(1, 0);
db res = -1;
for (int i = 1;i <= n;i++) for (int j = k;j <= n;j++) {
res = max(res, dp[i][j]);
}
if (res >= 0) return 1;
return 0;
} int main () {
cin >> n >> k;
for (int i = 1;i <= n;i++) cin >> v[i];
for (int i = 1;i <= n;i++) cin >> w[i];
for (int i = 1;i < n;i++) {
int x, y;
cin >> x >> y;
add(x, y); add(y, x);
}
db l = 0, r = 200000; //二分
while (r - l > 0.0001) { //注意精度
db mid = (l + r) / 2;
if (check(mid)) l = mid;
else r = mid - 0.0001;
}
printf("%.2lf", l);
return 0;
}

P3874 砍树 题解的更多相关文章

  1. [7.18NOIP模拟测试5]砍树 题解(数论分块)

    题面(加密) 又考没学的姿势……不带这么玩的…… 考场上打了个模拟 骗到30分滚粗了 稍加思考(滑稽)可将题面转化为: 求一个最大的$d$,使得 $\sum \limits _{i=1}^n {(\l ...

  2. 7. 18 test 砍树题解

    (题面保密,内部人员可览) 首先观察题面,可得出如下公式 ∑(ceil(a[i] /d)*d−a[i])≤k 其中,ceil(a[i] /d)表示在需要被砍伐之前所经过的轮数,ceil函数是为了保证一 ...

  3. 7.18 NOIP模拟测试5 星际旅行+砍树+超级树

    T1 星际旅行 题意:n个点,m条边,无重边,有自环,要求经过m-2条边两次,2条边一次,问共有多少种本质不同的方案.本质不同:当且仅当至少存在一条边经过次数不同. 题解:考试的时候理解错题,以为他是 ...

  4. AC日记——砍树 codevs 1388

    1388 砍树  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 伐木工人米尔科需要砍倒M米长的木 ...

  5. 1369 xth 砍树

    1369 xth 砍树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 在一个凉爽的夏夜,xth 和 ...

  6. [CSP-S模拟测试]:砍树(数学+模拟)

    题目传送门(内部题1) 输入格式 第一行两个整数$n$,$k$,代表树苗的数量和最大看书的总长度.第二行n个整数$a_i$,代表林先森希望每棵树苗的最终高度. 输出格式 一行一个整数,代表最大可能的d ...

  7. noip模拟8[星际旅行·砍树·超级树·求和]

    也不能算考得好,虽然这次A了一道题,但主要是那道题太简单了,没啥成就感,而且有好多人都A掉了 除了那一道,其他的加起来一共拿了25pts,这我能咋办,无奈的去改题 整场考试的状态并不是很好啊,不知道是 ...

  8. NOIP模拟测试5「星际旅行·砍树·超级树」

    星际旅行 0分 瞬间爆炸. 考试的时候觉得这个题怎么这么难, 打个dp,可以被儿子贡献,可以被父亲贡献,还有自环,叶子节点连边可以贡献,非叶子也可以贡献,自环可以跑一回,自环可以跑两回, 关键是同一子 ...

  9. codevs 1388 砍树

    时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题目描述 Description 伐木工人米尔科需要砍倒M米长的木材.这是一个对米尔科来说很容易的工作,因为他有一 ...

  10. Vijos1448校门外的树 题解

    Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...

随机推荐

  1. 11g ADG级联备库基础测试环境准备

    客户通过duplicate生产备库的方式创建cascade备库. 发现每次都会遇到两个文件报错,ORA-17628: Oracle error 19505错误,且每一次跑,报错文件不一样. 现在想帮客 ...

  2. 【Linux】(小白向)详解VirtualBox网络配置-配置Linux网络

    本文时间 2023-05-18 作者:sugerqube漆瓷 本文面向新手,重在理解会舍弃不少精密的理论,还请大佬们见谅. 本文目标:成功使用ssh工具登录linux,同时linux能连接外网. 网络 ...

  3. Python这样读写Excel数据,这样简直不要太粗暴!

    什么是xlrd&xlwt? xlrd和xlwt是Python语言中,读取和写入Excel数据的扩展工具.xlrd为xls文件read库,xlwt为xls文件write库.具体请看xlrd百度百 ...

  4. react eject提示This git repository has untracked files or uncommitted changes:

    在yarn eject 但时 老是提示This git repository has untracked files or uncommitted changes: Remove untracked ...

  5. 美女同事的烦恼:如何配置 Apache SkyWalking 告警?

    小婉 技术部基本上是一个和尚庙,女生非常少,即使有女生也略微有点抽象,小婉就不一样,她气质绝佳. 上午,同事小婉刚才从老板办公室里出来,看上去一脸不悦的样子.为了表示对同事的关(ba)心(gua),我 ...

  6. 【Python&GIS】GDAL栅格转面&计算矢量面积

            GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库.它利用抽象数据模型来表达所支持的各种文件格式.它 ...

  7. shell编程-提取IP地址

    1.使用cut文本处理工具提取 [root@hadoop129 scripts]# ifconfig ens33 | grep netmask | cut -d " " -f 10 ...

  8. STL-priority_queue(ACM)

    1.无法访问v.front().v.back() 2.是一个 堆,默认为大根堆,改造后为小根堆 大根堆 重构函数(默认)(大根堆) priority_queue<int> v; 基本操作 ...

  9. 如何使用C#中的Lambda表达式操作Redis Hash结构,简化缓存中对象属性的读写操作

    Redis是一个开源的.高性能的.基于内存的键值数据库,它支持多种数据结构,如字符串.列表.集合.散列.有序集合等.其中,Redis的散列(Hash)结构是一个常用的结构,今天跟大家分享一个我的日常操 ...

  10. PTA 21级数据结构与算法实验6—图论

    目录 7-1 邻接矩阵表示法创建无向图 7-2 邻接表创建无向图 7-3 图深度优先遍历 7-4 单源最短路径 7-5 列出连通集 7-6 哈利·波特的考试 7-7 家庭房产 7-8 森森美图 7-9 ...