JZdalao昨天上课讲的题目,话说JSOI的题目是真的不难,ZJOI的题目真的是虐啊!

题意很简单,抽象一下就是:有一棵树,一次只能选从根到某个节点上的链上的所有点,问从中取出k个节点所得到的总价值和总代价的比最大是多少。

像这种比值最大的题目,很容易让人联想到分数规划

关于分数规划的姿势,可以自行百度

对于题意进行进一步分析,得到要求的是:

max{∑v[i]/∑w[i]}(if i is chosen)

因此我们设x,二分x,看看是否存在:

max{∑v[i]/∑w[i]}>=x(if i is chosen)

移项得每个点的权值c[i]:

c[i]=v[i]-x*w[i](1<=i<=n)

所以我们得出c[i],然后看看能否在树上找出满足题意的点集使得点权和大于等于0

所以要找出最大值,再考虑树形DP

但是一般的背包DP和多叉树转二叉树DP都是O(n^3)的

所以可以用DFS序来完成这种树上的n个点选m个点的DP

具体如下:

  1. 预处理出原树的DFS序,以及每个节点的子树大小

  2. 进行DP 用f[i][j]表示DFS序列中前i-1个点中选取j个点中得到的最大点权和

  3. 对于每一个f[i][j],可以转移:

  • f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+c[s[i]]) (选这个点)

  • f[i+size[s[i]]][j]=max(f[i+size[s[i]]][j],f[i][j]) (不选这个点,则直接跳过整棵子树

最后判断f[n+1][k]是否大于等于0

注意这里的人数不包括根节点,因此k要加1

CODE

// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
using namespace std;
typedef double DB;
const int N=2505;
const DB EPS=1e-5,INF=1e9;
struct edge
{
int to,next;
}e[N];
int head[N],v[N],w[N],size[N],s[N],n,k,x,cnt,tot;
DB f[N][N],c[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void add(int x,int y)
{
e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
}
inline void DFS(int now)
{
s[++tot]=now; size[now]=1;
for (register int i=head[now];i!=-1;i=e[i].next)
DFS(e[i].to),size[now]+=size[e[i].to];
}
inline DB max(DB a,DB b)
{
return a>b?a:b;
}
inline bool check(DB x)
{
register int i,j;
for (i=1;i<=n;++i)
c[i]=(DB)v[i]-(DB)x*w[i];
for (i=1;i<=tot+1;++i)
for (j=0;j<=k;++j)
f[i][j]=-INF;
for (f[1][0]=0,i=1;i<=tot;++i)
for (j=0;j<=k;++j)
{
f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+c[s[i]]);
f[i+size[s[i]]][j]=max(f[i+size[s[i]]][j],f[i][j]);
}
return f[tot+1][k]>=0;
}
int main()
{
register int i;
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
memset(e,-1,sizeof(e));
memset(head,-1,sizeof(head));
read(k); read(n); ++k;
for (i=1;i<=n;++i)
{
read(w[i]); read(v[i]); read(x);
add(x,i);
}
DFS(0);
DB l=0,r=1e4;
while (r-l>EPS)
{
DB mid=(DB)(l+r)/2;
if (check(mid)) l=mid; else r=mid;
}
printf("%.3lf",l);
return 0;
}

Luogu P4322 [JSOI2016]最佳团体的更多相关文章

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

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

  2. p4322 [JSOI2016]最佳团体

    传送门 分析 我们不难发现这是一棵树 于是01分数规划然后树上dp即可 代码 #include<iostream> #include<cstdio> #include<c ...

  3. 洛谷$P4322\ [JSOI2016]$最佳团体 二分+$dp$

    正解:二分+$dp$ 解题报告: 传送门$QwQ$ 这题长得好套路嗷,,,就一看就看出来是个$01$分数规划+树形$dp$嘛$QwQ$. 考虑现在二分的值为$mid$,若$mid\leq as$,则有 ...

  4. [JSOI2016]最佳团体 DFS序/树形DP

    题目 洛谷 P4322 [JSOI2016]最佳团体 Description 茜茜的舞蹈团队一共有\(N\)名候选人,这些候选人从\(1\)到\(N\)编号.方便起见,茜茜的编号是\(0\)号.每个候 ...

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

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

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

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

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

    BZOJ4753: [Jsoi2016]最佳团体(分数规划+树上背包) 标签:题解 阅读体验 BZOJ题目链接 洛谷题目链接 具体实现 看到分数和最值,考虑分数规划 我们要求的是一个\(\dfrac{ ...

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

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

  9. BZOJ.4753.[JSOI2016]最佳团体(01分数规划 树形背包DP)

    题目链接 \(Description\) 每个点有费用si与价值pi,要求选一些带根的连通块,总大小为k,使得 \(\frac{∑pi}{∑si}\) 最大 \(Solution\) 01分数规划,然 ...

随机推荐

  1. Android长按事件和点击事件 冲突问题

    长按点击的时候默认会触发点击事件,android系统是优先点击的,并且没有返回值:而长按事件是有返回值的,如果返回false,两个事件都会有响应,如果返回true则只响应长按事件.

  2. hashCode()与equals()方法的对比

        Java对于eqauls方法和hashCode方法是这样规定的: 1.如果两个对象相同,那么它们的hashCode值一定要相同: 2.如果两个对象的hashCode相同,它们并不一定相同(上面 ...

  3. .gitignore文件规则不起效的解决办法

    在一个项目里面,多少会有一些文件是不需要上传到git上面的,比如node的依赖模块node_modules,这个文件夹超过10000个文件,大小也超过80M.所以,一个.gitignore文件省不了, ...

  4. Linux内存寻址之分段机制及分页机制【转】

    前言 本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制: 最近在学习Linux内核,读到<深入理解Linux内核>的内存寻址一章.原本以为 ...

  5. Centos 6.5-yum安装出现错误解决方案

    最近在用Centos 6.5 的时候出现了以下情况: 遇到这种问题试试以下方法: 1.检查是否能上网:ping www.baidu.com 如果显示没有连接的话,就说明没网,也就无法使用yum 命令安 ...

  6. 如何在linux centos 环境下运行.exe文件

    linux是不能运行window下的可执行文件的,必须借助于wine.百度了以下wine如下:   Wine (“Wine Is Not an Emulator” 的递归缩写)是一个能够在多种 POS ...

  7. 【转】Mysql学习---MySQL悲观锁中的排它锁

    [原文]https://www.toutiao.com/i6595305814087434760/ 悲观锁中的排它锁. 排它锁关键字:for update 特点:会锁住行或者表,防止其他事务进行修改操 ...

  8. IIS 安全设置

    这近网站中毒,以下把IIS安全设置记录一下,以便查阅. 1.对于不需要执行的目录,将处理程序映射中的编辑功能权限中的脚本去掉,这样即使上传了木马文件在此目录,也是无法执行的. 删除IIS默认的匿名用户 ...

  9. python基本语法:

    http://www.runoob.com/python/python-basic-syntax.html

  10. SQLServer 删除表中的重复数据

    create table Student(        ID varchar(10) not null,        Name varchar(10) not null, ); insert in ...