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. Python 开发者在迁移到 Go(lang) 时需要知道哪些事?

    [编者按]本文最早由 Repustate 发布,主要介绍将代码迁移至 Go(lang) 时的注意事项.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文. 这是一篇讲述将大块 Pyth ...

  2. Oracle EBS INV 查询物料无值 ECO

    查找物料的时候报错 没有输入值 解决方法: 针对FORM做trace 多查看几个生成的trace 搜索 MTL_SYSTEM_ITEMS_b 的信息 查看到最后面的语句(一般可直接查看) 看SQL 哪 ...

  3. SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析 (转载)

    在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...

  4. SQL Server如何附加只有mdf的数据库文件

    有时候SQL Server意外断电会导致SQL Server的ldf日志文件丢失或者损坏,这个时候你如果直接附加mdf文件到SQL Server会失败,这里提供一个方法可以还原只有mdf的数据库文件, ...

  5. Sql Server中的游标最好只用于有主键或唯一键的表

    游标cursor,我想大多数人都在sql server里面用过.当一个表数据量不太大的时候,游标还是可以用的,毕竟游标是循环一个表中每一行数据的最简便办法.但是如果你用一个游标去循环一个没有主键或唯一 ...

  6. 表格排序(tablesorter)

    1.在html页面的head中引用 <script src="/static/Bootstrap/js/jquery/jquery.tablesorter.min.js"&g ...

  7. PHP 8中数据类型

    PHP  一共支持八种数据类型 4种标量数据类型 boolean布尔型   只有两个值  true 和  flase integer整形  包括正整数和负整数,无小数位 float/double 浮点 ...

  8. 安装 Scala

    0. 说明 Scala 安装(Windows)  &  Scala 安装(Linux) 1. Scala 安装(Windows) 1.0 下载 Scala  下载地址 1.1 运行 Scala ...

  9. 【第一次玩Travis CI】终于弄好了我的马鸭

    真是不容易,我都要哭了.熬了半天终于弄完了!! 终于可以坐这儿挺会小曲,写写感受了. 作为一个程序写的不咋滴的程序员,倒是特别喜欢写博客,也是绝了. 高三的时候,用OneNote,后来转到Lofter ...

  10. Azure DevKit(AZ3166)源码找不到头文件问题

    Get “Error Presented: #include errors detected” when opening a project The error message is Error Pr ...