分析:

化简一下我们可以发现,suma*ans=sumb,那么我们考虑二分ans,之后做树形背包上做剪枝。

时间复杂度证明,By GXZlegend O(nklogans)

附上代码:

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
#define N 2505
#define eps 5e-4
#define max(a,b) ((a)<(b)?(b):(a))
double f[N][N],ans;
int a[N],b[N],dep[N],head[N],cnt,k,n,siz[N];
struct node
{int to,next;
}e[N<<1];
void add(int x,int y)
{e[cnt].to=y;e[cnt].next=head[x];head[x]=cnt++;return ;
}
void dfs(int x,int from)
{dep[x]=dep[from]+1;siz[x]=1;if(x)f[x][1]=-ans*a[x]+b[x];for(int i=head[x];i!=-1;i=e[i].next){int to1=e[i].to;if(to1!=from){dfs(to1,x);int o=min(k,siz[x]+siz[to1]),u=min(k,siz[to1]);for(int j=o;j>=1;j--){for(int l=max(j-siz[x],1);l<=u;l++){if(l>j)break;f[x][j]=max(f[x][j],f[x][j-l]+f[to1][l]);}}siz[x]+=siz[to1];}}
}
bool check(double x)
{for(int i=0;i<=n;i++)for(int j=0;j<=k;j++)f[i][j]=-1e9;dep[0]=f[0][0]=0;ans=x;dfs(0,0);if(f[0][k]>0)return 1;return 0;
}
int main()
{// freopen("sales.in","r",stdin);// freopen("sales.out","w",stdout);memset(head,-1,sizeof(head));scanf("%d%d",&k,&n);for(int i=1;i<=n;i++){int x;scanf("%d%d%d",&a[i],&b[i],&x);add(x,i);}double l=0,r=10000;while(l<r-eps){double mid=(l+r)/2;if(check(mid))l=mid;else r=mid;}printf("%.3lf\n",l);return 0;
}

其实这种方法就能跑的飞起,虽然是递归的,并且状态和转移比较多。

其实还有别的方法,比如说将它转化为dfs序上做背包。

我们知道,选择一个必须包含根的联通块,我们就可以这样考虑,状态和上面的差不多,f[i][j]表示dfs序上选择第i个点,在i-n中选j个的最大答案

转移:f[i][j]=f[i+1][j-1]+x*a[idx[i]]+b[idx[i]]和f[i][j]=max(f[i][j],f[i+siz[idx[i]][j]);

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

附上代码:

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
#define N 2505
#define eps 5e-4
#define max(a,b) ((a)<(b)?(b):(a))
double f[N][N],ans;
int a[N],b[N],head[N],cnt,k,n,idx[N],x,siz[N],tims;
struct node
{int to,next;
}e[N<<1];
void add(int x,int y)
{e[cnt].to=y;e[cnt].next=head[x];head[x]=cnt++;return ;
}
void dfs(int x,int from)
{idx[++tims]=x;siz[x]=1;for(int i=head[x];i!=-1;i=e[i].next){int to1=e[i].to;if(to1!=from){dfs(to1,x);siz[x]+=siz[to1];}}
}
bool check(double x)
{for(int i=1;i<=n+2;i++){for(int j=0;j<=k;j++){f[i][j]=-1e9;}}f[n+2][0]=0;for(int i=n+1;i>=1;i--){int t=idx[i];int u=min(k,n+2-i);if(i!=1){for(int j=u;j>=1;j--){f[i][j]=f[i+1][j-1]-x*a[t]+b[t];}}else{for(int j=k;j>=1;j--){f[i][j]=f[i+1][j];}}for(int j=u;j>=0;j--){f[i][j]=max(f[i][j],f[i+siz[t]][j]);}}if(f[1][k]>0)return 1;return 0;
}
int main()
{// freopen("sales.in","r",stdin);// freopen("sales.out","w",stdout);memset(head,-1,sizeof(head));scanf("%d%d",&k,&n);for(int i=1;i<=n;i++){int x;scanf("%d%d%d",&a[i],&b[i],&x);add(x,i);}dfs(0,0);double l=0,r=10000;while(l<r-eps){double mid=(l+r)/2;if(check(mid))l=mid;else r=mid;}printf("%.3lf\n",l);return 0;
}

  

转载于:https://www.cnblogs.com/Winniechen/p/9094630.html

[Jsoi2016]最佳团体 BZOJ4753 01分数规划+树形背包/dfs序相关推荐

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

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

  2. P1642 规划 01分数规划+树形DP

    $ \color{#0066ff}{ 题目描述 }$ 某地方有N个工厂,有N-1条路连接它们,且它们两两都可达.每个工厂都有一个产量值和一个污染值.现在工厂要进行规划,拆除其中的M个工厂,使得剩下的工 ...

  3. P4322-[JSOI2016]最佳团体【0/1分数规划,树形背包】

    正题 题目链接:https://www.luogu.com.cn/problem/P4322 题目大意 nnn个点的一棵树,每个节点有一个(si,pi)(s_i,p_i)(si​,pi​),选择一个点 ...

  4. P4322 [JSOI2016]最佳团体(分数规划树上背包)

    P4322 [JSOI2016]最佳团体(分数规划&树上背包) 分数问题,首先转为二分性判定问题. 每个结点的值变为:vali=ai−mid×bival_i=a_i-mid\times b_i ...

  5. bzoj 1690: [Usaco2007 Dec]奶牛的旅行(01分数规划--最优比率环)

    01分数规划问题: 给你n个物品,a[i]表示第i个物品的收益,b[i]表示代价,x[i]表示选或不选,求一个最佳方案使得下式取值最大 通用解: 当然是从式子上考虑,定义函数F[cnt]如下: 其中c ...

  6. 对于0-1分数规划的Dinkelbach算法的分析

    分类: 数学理论及总结 2012-08-16 10:12  278人阅读  评论(0)  收藏  举报 算法 c 优化 fp 武钢三中 吴豪[译] 摘要: 0-1分数规划问题是指求出解集{xi|xi= ...

  7. poj2976(0-1分数规划)

    0-1分数规划 设x[i]等于1或0. 则我们所求的比率 rate = ∑(cost[i] * x[i]) / ∑(cost[i] * x[i]), 0≤i<m . z( rate ) = ∑( ...

  8. 点分治问题 ----------- luoguP2942 [WC2010]重建计划 [点分治 + bfs + 单调队列 + 预处理建树 + 二分 + 01分数规划]

    题目链接 解题思路: 1.对于这个Avgvalue=∑e∈sv(e)∣s∣Avgvalue = \frac{\sum_{e\in s}v(e)}{|s|}Avgvalue=∣s∣∑e∈s​v(e)​ ...

  9. 解题报告:AcWing 1165. 单词环(01分数规划、hash、经验优化)

    本题的关键在于: 建图 01分数规划 本题的数据过大,如果直接spfa判断会TLE,因此我们使用经验优化,就是如果所有的点入队的次数过多,比如大于100000,那么我们直接认为它是存在正环的.(免去T ...

最新文章

  1. 写 Python 代码不可不知的函数式编程技术
  2. java VM 推荐的命令行设置
  3. 克隆真人语音只要1句话,AI问诊超96.4%全科医生!科大讯飞年度黑科技大秀,余承东都来了...
  4. python脚本备份网络交换的命令
  5. Chrome反压缩JS代码:Pretty Print显示可读代码
  6. matlab中读文件的行数_Matlab中读取txt文件的几种方法
  7. 天津大学仁爱学院c语言期末考试题,天津大学《C语言程序设计》2016年7月考试期末大作业...
  8. [软技能] 在前后端分离项目里,请说说前端传递的token的流程?
  9. 双目视觉几何框架详解(玉米专栏8篇汇总)
  10. createsamples.cpp中生成vec文件的实现及详细注释、图解——人脸识别的尝试系列(三)
  11. update set操作 根据变量选择colum
  12. 文件操作--设置文件属性、获取文件属性
  13. 路由器经常掉线,必须重新插拔网线才能上网,什么原因?
  14. 广义积分中值定理的证明(柯西中值定理)
  15. Spring 5.0.3.RELEASE中的 Kotlin 语言等支持
  16. 23 种设计模式(Java代码演示版)
  17. 通过QQ互联实现网站第三方登录
  18. 《论文阅读》Multi-Task Learning of Generation and Classification for Emotion-Aware Dialogue Response Gener
  19. java unicode是什么意思_(转)谈谈对Java中Unicode、编码的理解
  20. 刷脸支付有效的风险监控和预防措施

热门文章

  1. LISTVIEW嵌套GRIDVIEW的一些处理(点击GRIDVIEW的条目,能够显示他在LISTVIEW中的位置)(对这篇文章的优化处理,不每次都new onItemClickListener)...
  2. PostgreSql与sqlserver对比杂记
  3. SharePoint 2013的100个新功能之网站管理(二)
  4. java 文件 加解密_Java实现文件的加密解密功能示例
  5. c语言c99标准_如何成为一名优秀的 C 语言程序员?
  6. java mybatis enum_mybatis处理枚举类的简单方法
  7. mysql sleep详解_mysql sleep链接过多的原因及解决办法
  8. Angular使用mathjs
  9. 记录一下增加标定评价标准的过程
  10. 钉钉需要什么java知识_Java钉钉开发_01_开发前的准备