洛谷P4322.最佳团体
题目大意
一个 \(n(1\leq n\leq 2500)\) 个节点的森林,每个点 \(i\) 有权值 \(s_{i},p_{i}(0<s_{i},p_{i}\leq 10^4)\) 以及父亲 \(r_{i}\) 。每个节点可以被选择的前提是其父亲已经被选择,从中选出 \(k(1\leq k\leq n)\) 个节点,使得 \(\sum_{j=1}^{k}\frac{p_{j}}{s_{j}}\) 的值最大,求出这个值。
思路
这很显然是一个分数规划问题,我们可以让每个节点 \(i\) 的权值为 \(p_{i}-s_{i}\times mid\) ,然后二分来判断。我们用节点 \(0\) 作为根把所有森林连起来变成一棵树,每次判断时作树形 \(dp\) ,设 \(dp[v,i]\) 为在以 \(v\) 为根的子树中选取了 \(i\) 个点所获得的最大权值,于是在合并子树 \(to\) 的过程中,有:
\]
\]
每次 \(dp\) 时将所有 \(dp[v,0]\) 初始为 \(0\) ,其余为 \(-inf\) 。最后根据 \(dp[0,k]\) 是否 \(\geq0\) 来判断即可,每次 \(check\) 可以 \(O(n^2)\) 完成,因为每两个节点 \(x,y\) 仅会在 \(lca(x,y)\) 处对遍历次数产生 \(1\) 的贡献,复杂度 \(O(n^2logn)\) 。
代码
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2+1
//#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 2510;
vector<int>G[maxn];
LL K, N, S[maxn], P[maxn], R[maxn];
double dp[maxn][maxn];
double val[maxn];
LL vsize[maxn];
void add_edge(int from, int to)
{
G[from].push_back(to);
}
void dfs(int v)
{
vsize[v] = 1;
dp[v][0] = 0;
if (!G[v].size())
{
dp[v][1] = val[v];
return;
}
for (int i = 0; i < G[v].size(); i++)
{
int to = G[v][i];
dfs(to);
for (int j = vsize[v] - 1; j >= 0; j--)
{
for (int k = vsize[to]; k >= 0; k--)
dp[v][j + k] = max(dp[v][j + k], dp[v][j] + dp[to][k]);
}
vsize[v] += vsize[to];
}
if (v)
{
for (int i = vsize[v]; i > 0; i--)
dp[v][i] = dp[v][i - 1] + val[v];
}
}
bool check(double x)
{
for (int i = 0; i <= N; i++)
{
for (int j = 1; j <= K; j++)
dp[i][j] = -inf;
}
for (int i = 1; i <= N; i++)
val[i] = P[i] - S[i] * x;
dfs(0);
if (dp[0][K] - 0 > -eps)
return true;
return false;
}
void solve()
{
double lo = 0, hi = inf;
for (int i = 1; i <= 100; i++)
{
double mid = (lo + hi) / 2;
if (check(mid))
lo = mid;
else
hi = mid;
}
cout << setiosflags(ios::fixed) << setprecision(3) << lo << endl;
}
int main()
{
IOS;
cin >> K >> N;
for (int i = 1; i <= N; i++)
{
cin >> S[i] >> P[i] >> R[i];
add_edge(R[i], i);
}
solve();
return 0;
}
洛谷P4322.最佳团体的更多相关文章
- 洛谷$P4322\ [JSOI2016]$最佳团体 二分+$dp$
正解:二分+$dp$ 解题报告: 传送门$QwQ$ 这题长得好套路嗷,,,就一看就看出来是个$01$分数规划+树形$dp$嘛$QwQ$. 考虑现在二分的值为$mid$,若$mid\leq as$,则有 ...
- 洛谷 P1336 最佳课题选择
P1336 最佳课题选择 题目提供者 yeszy 标签 动态规划 福建省历届夏令营 传送门 难度 尚无评定 题目描述 Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择.由于课 ...
- 洛谷 P2096 最佳旅游线路
某旅游区的街道成网格状.其中东西向的街道都是旅游街,南北向的街道都是林阴道.由于游客众多,旅游街被规定为单行道,游客在旅游街上只能从西向东走,在林阴道上则既可从南向北走,也可以从北向南走. 阿龙想到这 ...
- [JSOI2016]最佳团体 DFS序/树形DP
题目 洛谷 P4322 [JSOI2016]最佳团体 Description 茜茜的舞蹈团队一共有\(N\)名候选人,这些候选人从\(1\)到\(N\)编号.方便起见,茜茜的编号是\(0\)号.每个候 ...
- Bzoj4753/洛谷P4432 [JSOI2016]最佳团体(0/1分数规划+树形DP)
题面 Bzoj 洛谷 题解 这种求比值最大就是\(0/1\)分数规划的一般模型. 这里用二分法来求解最大比值,接着考虑如何\(check\),这里很明显可以想到用树形背包\(check\),但是时间复 ...
- LUOGU P4322 [JSOI2016]最佳团体(0/1分数规划+树形背包)
传送门 解题思路 一道0/1分数规划+树上背包,两个应该都挺裸的,话说我常数为何如此之大..不吸氧洛谷过不了啊. 代码 #include<iostream> #include<cst ...
- BZOJ4753: [Jsoi2016]最佳团体(分数规划+树上背包)
BZOJ4753: [Jsoi2016]最佳团体(分数规划+树上背包) 标签:题解 阅读体验 BZOJ题目链接 洛谷题目链接 具体实现 看到分数和最值,考虑分数规划 我们要求的是一个\(\dfrac{ ...
- 洛谷 P2279 03湖南 消防局的设立
2016-05-30 16:18:17 题目链接: 洛谷 P2279 03湖南 消防局的设立 题目大意: 给定一棵树,选定一个节点的集合,使得所有点都与集合中的点的距离在2以内 解法1: 贪心 首先D ...
- 洛谷P2756飞行员配对方案问题 P2055假期的宿舍【二分图匹配】题解+代码
洛谷 P2756飞行员配对方案问题 P2055假期的宿舍[二分图匹配] 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架 ...
随机推荐
- ansible roles实践——安装httpd
1. vim httpd.yml 2.执行
- 通俗易懂详解iptables
防火墙相关概念 从逻辑上讲.防火墙可以大体分为主机防火墙和网络防火墙. 主机防火墙:针对于单个主机进行防护. 网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网. ...
- windows下使用LTP分词,安装pyltp
1.LTP介绍 ltp是哈工大出品的自然语言处理工具箱, 提供包括中文分词.词性标注.命名实体识别.依存句法分析.语义角色标注等丰富. 高效.精准的自然语言处理技术.pyltp是python下对ltp ...
- aws vpc 知识总结(助理级)
一 什么是vpc? Amazon Virtual Private Cloud(Amazon VPC)使您可以将AWS资源启动到您定义的虚拟网络中. 虚拟的云计算. /* 1 默认vpc ? 创建一个具 ...
- ByteArrayOutputStream内存流
简介 ByteArrayOutputStream 对byte类型数据进行写入的类 相当于一个中间缓冲层,创建ByteArrayOutputStream类实例时,内存中会创建一个byte数组类型的缓冲区 ...
- JAVA多线程学习五:线程范围内共享变量&ThreadLocal
一.概念 可以将每个线程用到的数据与对应的线程号存放到一个map集合中,使用数据时从这个集合中根据线程号获取对应线程的数据,就可以实现线程范围内共享相同的变量. 二.代码 Runnable中的run( ...
- shell脚本之循环语句与函数
shell脚本之循环语句与函数 echo的用法: echo -n #表示不换行输出 echo -e #输出转义字符,将转义后的内容输出到屏幕上 转义字符: \n :换行,被输出的字符从"\n ...
- python基础语法_7运算符
http://www.runoob.com/python3/python3-basic-operators.html#ysf7 目录 Python语言支持以下8类型的运算符: 算术运算符(-,+,*, ...
- MySQL里的那些日志们
该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引.事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sql,减少SQL执行时 ...
- 理解Faster R-CNN
首先放R-CNN的原理图 显然R-CNN的整过过程大致上划分为四步: 1.输入图片 2.生成候选窗口 3.对局部窗口进行特征提取(CNN) 4.分类(Classify regions) 而R-CNN的 ...