BZOJ4753: [Jsoi2016]最佳团体
时间:2022-05-08
本文章向大家介绍BZOJ4753: [Jsoi2016]最佳团体,主要内容包括Description、Input、Output、Sample Input、Sample Output、HINT、Source、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
Description
JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号。方便起见,JYY的编号是0号。每个候选人都由一位
编号比他小的候选人Ri推荐。如果Ri=0则说明这个候选人是JYY自己看上的。为了保证团队的和谐,JYY需要保证,
如果招募了候选人i,那么候选人Ri"也一定需要在团队中。当然了,JYY自己总是在团队里的。每一个候选人都有
一个战斗值Pi",也有一个招募费用Si"。JYY希望招募K个候选人(JYY自己不算),组成一个性价比最高的团队。
也就是,这K个被JYY选择的候选人的总战斗值与总招募总费用的比值最大。
Input
输入一行包含两个正整数K和N。
接下来N行,其中第i行包含3个整数Si,Pi,Ri表示候选人i的招募费用,战斗值和推荐人编号。
对于100%的数据满足1≤K≤N≤2500,0<"Si,Pi"≤10^4,0≤Ri<i
Output
输出一行一个实数,表示最佳比值。答案保留三位小数。
Sample Input
1 2 1000 1 0 1 1000 1
Sample Output
0.001
HINT
2017.9.12新加数据一组 By GXZlegend
Source
应该是比较裸的题目
01分数规划+树形依赖背包。
01分数规划的话按照套路二分检验,注意设置好精度
树形依赖背包注意在枚举的时候上限应该在枚举之后更改否则会被卡成O(N^3log ans)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e6+10,INF=1e4+10;
inline char nc()
{
static char buf[MAXN],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
char c=nc();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
return x*f;
}
int N,K;
int S[MAXN],P[MAXN],R[MAXN];
struct node
{
int u,v,nxt;
}edge[MAXN];
int head[MAXN];
int num=1;
inline void AddEdge(int x,int y)
{
edge[num].u=x;
edge[num].v=y;
edge[num].nxt=head[x];
head[x]=num++;
}
double dp[2501][2501],/*i处,选了j个*/siz[MAXN],w[MAXN];
void find(int now)
{
siz[now]=1;
for(int i=head[now];i!=-1;i=edge[i].nxt)
find(edge[i].v),siz[now]+=siz[edge[i].v];
}
void dfs(int now)
{
int tot=0,b=0;
if(now) dp[now][1]=w[now],tot=1,b++;
else dp[now][0]=0;
for(int i=head[now];i!=-1;i=edge[i].nxt)
{
dfs(edge[i].v);
for(int j=tot;j>=b;j--)//背包容量
for(int k=1;k<=siz[edge[i].v];k++)
dp[now][j+k]=max(dp[now][j+k],dp[now][j]+dp[edge[i].v][k]);
tot+=siz[edge[i].v];//必须在后面加
}
}
bool check(double val)
{
memset(dp,0xc2,sizeof(dp));
for(int i=1;i<=N;i++) w[i]=P[i]-val*S[i];
dfs(0);
return dp[0][K]>=0;
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
memset(head,-1,sizeof(head));
K=read(),N=read();
for(int i=1;i<=N;i++)
{
S[i]=read(),P[i]=read(),R[i]=read();
AddEdge(R[i],i);
}
find(0);
double l=0,r=INF;
double ans=0;
while(r-l>1e-5)
{
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.3lf",(l+r)/2);
return 0;
}
- BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)
- 微信公众平台开发
- BZOJ 1115: [POI2009]石子游戏Kam (阶梯nim)
- php性能监测模块XHProf
- BZOJ 1022: [SHOI2008]小约翰的游戏John (Anti-nim)
- 洛谷P2252 取石子游戏(威佐夫博弈)
- HDU 3032 Nim or not Nim?(Multi-Nim)
- POJ 2311 Cutting Game(二维SG+Multi-Nim)
- js去掉html标签和去掉字符串文本的所有的空格
- php操作memcache的使用测试总结
- linux awk命令详解
- php str_split 解决中文
- PHP汉字转拼音函数
- 51NOD 1185 威佐夫游戏 V2(威佐夫博弈)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Alibaba开源Java诊断工具Arthas简单介绍
- 气象编程 | Google Earth Engine for R——提供250+ 实例
- Anaconda安装和使用
- Redhat7安装docker
- 有个笔记本就可以玩一玩Hadoop
- java如何将String转换为Int
- java中如何将数组转换为List
- 从一个多层嵌套循环中直接跳出
- 如何给3个布尔变量,当其中有2个或者2个以上为true才返回true
- 比较java枚举成员使用equal还是==
- java如何将String转换为enum
- Markdown极简入门教程(1)—为什么要学习Markdown
- Markdown极简入门教程(2)—斜体和粗体
- 标题—Markdown极简入门教程(3)
- 链接—Markdown极简入门教程(4)