BZOJ4753: [Jsoi2016]最佳团体(分数规划+树上背包)

标签:题解

阅读体验

BZOJ题目链接 洛谷题目链接

具体实现

看到分数和最值,考虑分数规划

我们要求的是一个\(\dfrac{\sum P_i}{\sum S_i}\)最大对吧,考虑二分一个答案\(mid\)

那么就会有合法条件\(\dfrac{\sum P_i}{\sum S_i}\ge mid\),化简一下:\(\sum{(P_i-S_i×mid)}\ge 0\)

所以每次二分一个\(mid\)之后得到一个新数组v[i]=P[i]-S[i]×mid,我们跑背包\(check\)它最后是否大于等于\(0\)就可以了,因为有约束条件,所以把树建出来跑树上背包

dp[i][j]表示\(i\)节点选了\(j\)个凑出的\(v\)的最大值,我们最后就只要判断dp[0][K+1]>=0就可以啦

等一下!

这个\(dp\)的转移看上去向\(n^2\)的啊,再乘上\(Dfs\)的\(n\)的复杂度不就复杂度假了吗

其实不然,总体来看,每一对节点的\(dp\)状态只会在他们的\(Lca\)处被转移一次,想一想为什么(我想了挺久),所以复杂度就是\(n^2\)的啦

然而它还是卡常啊,最后\(Junlier\)就卡了很久,终于\(988ms\)卡过去了。。。

代码

#include<bits/stdc++.h>
#define il inline
#define rg register
#define ldb double
#define lst long long
#define rgt register int
#define N 2550
#define pb push_back
#define qw G[now][i]
using namespace std;
const lst Inf=1e18;
const ldb eps=1e-4;
il int read()
{
int s=0,m=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')m=1;ch=getchar();}
while( isdigit(ch))s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
} int K,n,Dex;
int siz[N];
struct LJL{int S,P,fa;}ljl[N];
ldb v[N],tmp[N],dp[N][N],Ans;
vector<int> G[N]; il void Merge(rgt x,rgt y)
{
for(rgt i=0;i<=K+1;++i)tmp[i]=-Inf;
for(rgt i=1,up;i<=siz[x];++i)
{
up=min(K+1-i,siz[y]);
for(rgt j=1;j<=up;++j)
tmp[i+j]=max(tmp[i+j],dp[y][j]+dp[x][i]);
}for(rgt i=0;i<=K+1;++i)dp[x][i]=max(dp[x][i],tmp[i]);
} void Dfs(rgt now)
{
for(rgt j=0;j<=K+1;++j)dp[now][j]=-Inf;
dp[now][1]=v[now],siz[now]=1;
for(rgt i=0;i<G[now].size();++i)
Dfs(qw),Merge(now,qw),siz[now]+=siz[qw];
} il bool check(ldb lim)
{
for(rgt i=1;i<=n;++i)
v[i]=ljl[i].P-ljl[i].S*lim;
Dfs(0);return dp[0][K+1]>=0;
} int main()
{
K=read(),n=read();
for(rgt i=1;i<=n;++i)
{
ljl[i]=(LJL){read(),read(),read()};
G[ljl[i].fa].pb(i);
}ldb le=eps,ri=1e5,mid;
while(ri-le>eps)
{
mid=(le+ri)/2;
if(check(mid))Ans=mid,le=mid+eps;
else ri=mid-eps;
}return printf("%.3lf\n",Ans),0;
}

BZOJ4753: [Jsoi2016]最佳团体(分数规划+树上背包)的更多相关文章

  1. 【bzoj4753】[Jsoi2016]最佳团体 分数规划+树形背包dp

    题目描述 JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号.方便起见,JYY的编号是0号.每个候选人都由一位编号比他小的候选人Ri推荐.如果Ri=0则说明这个候选人是JYY自己看上的.为了 ...

  2. 【BZOJ】4753: [Jsoi2016]最佳团体 01分数规划+树上背包

    [题意]n个人,每个人有价值ai和代价bi和一个依赖对象ri<i,选择 i 时 ri 也必须选择(ri=0时不依赖),求选择k个人使得Σai/Σbi最大.n<=2500,ai,bi< ...

  3. bzoj4753: [Jsoi2016]最佳团体(分数规划+树形依赖背包)

    菜菜推荐的“水题”虐了我一天T T...(菜菜好强强qwq~ 显然是个分数规划题,二分答案算出p[i]-mid*s[i]之后在树上跑依赖背包,选k个最大值如果>0说明还有更优解. 第一次接触树形 ...

  4. bzoj4753[JSOI2016]最佳团体

    题意:01分数规划,但可选的数字之间存在森林形的依赖关系(可以认为0号点是个虚根,因为并不能选). 虽然有森林形的依赖关系,但还是可以套分数规划的思路,二分答案k,判断是否存在一个比值大于k的方案 即 ...

  5. BZOJ4753 JSOI2016最佳团体(分数规划+树形dp)

    看到比值先二分答案.于是转化成一个非常裸的树形背包.直接暴力背包的话复杂度就是O(n2),因为相当于在lca处枚举每个点对.这里使用一种更通用的dfs序优化树形背包写法.https://www.cnb ...

  6. LUOGU P4322 [JSOI2016]最佳团体(0/1分数规划+树形背包)

    传送门 解题思路 一道0/1分数规划+树上背包,两个应该都挺裸的,话说我常数为何如此之大..不吸氧洛谷过不了啊. 代码 #include<iostream> #include<cst ...

  7. BZOJ 4753 [Jsoi2016]最佳团体 | 树上背包 分数规划

    BZOJ 4753 [Jsoi2016]最佳团体 | 树上背包 分数规划 又是一道卡精度卡得我头皮发麻的题-- 题面(--蜜汁改编版) YL大哥是24OI的大哥,有一天,他想要从\(N\)个候选人中选 ...

  8. BZOJ_4753_[Jsoi2016]最佳团体_树形背包+01分数规划

    BZOJ_4753_[Jsoi2016]最佳团体_树形背包+01分数规划 Description JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号.方便起见,JYY的编号是0号.每个候选人 ...

  9. 【BZOJ4753】最佳团体(分数规划,动态规划)

    [BZOJ4753]最佳团体(分数规划,动态规划) 题面 BZOJ Description JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号.方便起见,JYY的编号是0号.每个候选人都由一 ...

随机推荐

  1. pycharm不支持svn,是需要svn命令行工具没有安装(for windows)

    1. 安装svn命令行工具 Subversion for Windows下载https://sourceforge.net/projects/win32svn/?source=typ_redirect ...

  2. Django【第6篇】:Django之ORM单表操作(增删改查)

    django之数据库表的单表查询 一.添加表记录 对于单表有两种方式 # 添加数据的两种方式 # 方式一:实例化对象就是一条表记录 Frank_obj = models.Student(name =& ...

  3. django的自定义约束

    准备阶段 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag. 在app中创建templatetags模块(模块名只能是templa ...

  4. 047:创建和映射ORM模型

    创建ORM模型: ORM 模型一般都是放在 app 的 models.py 文件中.每个 app 都可以拥有自己的模型.并且如果这个模型想要映射到数据库中,那么这个 app 必须要放在 setting ...

  5. LeetCode--008--字符串转换整数 (atoi)(python)

    示例 1: 输入: "42"输出: 42示例 2: 输入: " -42"输出: -42解释: 第一个非空白字符为 '-', 它是一个负号.  我们尽可能将负号与 ...

  6. 状态管理工具对比vuex、redux、flux

    1.为什么要使用状态管路工具  在跨层级的组件之间传递信息,尤其是复杂的组件会非常困难.也不利于开发和维护,这时我们就a需要用到状态管理工具.     2.Flux

  7. Comet OJ - Contest #4 D求和 思维题

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...

  8. 安装JDK ,提示 错误1316 指定的账户已存在

    基于情况: 安装了一个JDK 后,在文件目录中删除了相关文件,之后再次安装,提示  错误1316 指定的账户已存在 造成原因:安装JDK,相当于安装了一个软件,要使用系统的软件卸载功能卸载,不能只删除 ...

  9. HPU personal training

    K - Two Contests 原题链接:https://agc040.contest.atcoder.jp/tasks/agc040_b?lang=en 题目大意: 给一个区间集合,将这些区间分为 ...

  10. CG-CTF | 上传绕过

    最近一直在做算法题,头都要大了,今天悄咪咪来一个web换换脑子,一发flag敲开♥[虽然知道这是个水题ε=ε=ε=┏(゜ロ゜;)┛]