思路:

先二分答案

f[x][j]表示在x的子树里选j个点

f[x][j+k]=max(f[x][j+k],f[x][j]+f[v[i]][k]);

初始化

x!=0 -> f[x][1]=p[x]-s[x]*mid

x=0 -> f[x][0]=0

类似4033的那样转移 看似O(n^3)实际O(n^2)

加一个二分 复杂度O(能过)

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
int n,K,s[N],p[N],r[N],first[N],next[N],v[N],tot,size[N];
double f[N][N],mid;
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void dfs(int x){
if(x){size[x]=;f[x][]=p[x]-s[x]*mid;}
else size[]=,f[][]=;
for(int i=first[x];~i;i=next[i]){
dfs(v[i]);
for(int j=size[x];j>=;j--){
for(int k=size[v[i]];k>=;k--){
f[x][j+k]=max(f[x][j+k],f[x][j]+f[v[i]][k]);
}
}
size[x]+=size[v[i]];
}
}
int main(){
memset(first,-,sizeof(first));
scanf("%d%d",&K,&n);
for(int i=;i<=n;i++){
scanf("%d%d%d",&s[i],&p[i],&r[i]);
add(r[i],i);
}
double l=,r=0x3f3f3f;
while(r-l>1e-){
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
f[i][j]=-0x3f3f3f;
mid=(l+r)/;
dfs();
if(f[][K]>)l=mid;
else r=mid;
}
printf("%.3lf\n",l);
}

最新文章

  1. 批量下载网站图片的Python实用小工具
  2. C#枚举中的位运算权限分配浅谈
  3. node.js Websocket实现扫码二维码登录---GoEasy
  4. Redis的发布订阅
  5. TCL_事务控制语言
  6. java EE 学习
  7. Eclipse4.3正式版已发布
  8. C++-传值与传引用的差别
  9. webstorm激活破解码+++使用技巧
  10. Photoshop 样式的角度/高度选择器控件
  11. 不允许用(a+b)/2这种方式求两个数的均值;如下程序在Linux和32位集成开发环境中运行
  12. 远程过程调用发展历程 WebAPI GRPC Hprose
  13. array_filter()函数
  14. sql server选取第m行到第n行的元组
  15. Linux ifconfig 命令
  16. Spark2.1.0模型设计与基本架构(上)
  17. phpstorm 配置 webpack @ 别名跳转
  18. IE盒模型与W3C盒模型区别
  19. OpenCV_基于局部自适应阈值的图像二值化
  20. 删除数据库的数据后让id从1开始算

热门文章

  1. CAD保存高版本的dwg(com接口)
  2. B+树知识点
  3. react 父组件给子组件传值
  4. 总结这几天js的学习内容
  5. enote笔记语言(5)——其他
  6. Linux之内核管理及故障排错
  7. VMware Workstation搭建Linux操作系统
  8. Django-----中间件Cookie
  9. WPF Style设置和模板化Template
  10. Linux系统自带服务罗列