zoukankan      html  css  js  c++  java
  • 【JSOI2016】最佳团体

    JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号
    方便起见,JYY的编号是0号。每个候选人都由一位编号比他小的候选人Ri推荐
    如果Ri= 0 ,则说明这个候选人是JYY自己看上的
    为了保证团队的和谐, JYY 需要保证,如果招募了候选人i,那么候选人R;也一定需要在团队中。
    当然了,JYY自己总是在团队里的。每一个候选人都有一个战斗值Pi ,也有一个招募费用Si
    JYY 希望招募K个候选人(JYY自己不算),组成一个性价比最高的团队
    也就是这K个被JYY选择的候选人的总战斗值与总招募费用的比值最大
    

    一看到比值最大,马上搞分数规划

    [dfrac{sum W_i}{sum C_i}leq x ]

    推出

    [sum W_i leq sum x * C_i ]

    所以

    [sum W_i-x*C_i leq 0 ]

    所以二分答案,在树上跑依赖背包即可

    代码:

    #include<bits/stdc++.h>
    #define eps 1e-5
    #define N 2505
    using namespace std;
    
    int k,n;
    double dp[N][N],d[N];
    
    struct People
    {
    	double s,p;
    	int f;
    }a[N];
    
    struct Edge
    {
    	int next,to;
    }edge[N<<1];
    int cnt=0,head[N];
    
    inline void add_edge(int from,int to)
    {
    	edge[++cnt].next=head[from];
    	edge[cnt].to=to;
    	head[from]=cnt;
    }
    
    int dfn[N],tms,las[N];
    void dfs(int u)
    {
    	dfn[u]=tms++;
    	for(register int i=head[u];i;i=edge[i].next) dfs(edge[i].to);
    	las[dfn[u]]=tms;
    }
    
    template<class T>inline void read(T &res)
    {
    	char c;T flag=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }
    
    double check(double mid)
    {
    	for(register int i=1;i<=n;++i)
    		d[dfn[i]]=a[i].p-(a[i].s*mid);
    	for(register int i=1;i<=n+1;++i)
    		for(register int j=0;j<=k+1;++j)
    			dp[i][j]=-1234567890;
    	for(register int i=0;i<=n;++i)
    	{
    		int maxn=min(i,k+1);
    		for(register int j=0;j<=maxn;++j)
    		{
    			if(dp[i][j]+d[i]>dp[i+1][j+1]) dp[i+1][j+1]=dp[i][j]+d[i];
    			if(dp[i][j]>dp[las[i]][j]) dp[las[i]][j]=dp[i][j];
    		}
    	}
    	return dp[n+1][k+1];
    }
    
    int main()
    {
    	read(k);read(n);
    	for(register int i=1;i<=n;++i)
    	{
    		scanf("%lf%lf",&a[i].s,&a[i].p);
    		read(a[i].f);
    		add_edge(a[i].f,i);
    	}
    	dfs(0);
    	double l=0.0,r=10000.0;
    	while(r-l>=eps)
    	{
    		double mid=(l+r)/2.0;
    		if(check(mid)>=eps) l=mid;
    		else r=mid;
    	}
    	printf("%.3lf",l);
    	return 0;
    }
    
  • 相关阅读:
    HttpServer发送数据到kafka
    Leetcode[33]-Search in Rotated Sorted Array
    站在淘宝天猫两大平台背后的平台
    JSON格式的时间“/Date(1530104033000)/”格式转为正常的年-月-日 格式的代码
    火星坐标、百度坐标、WGS84坐标转换代码(JS、python版)
    echart 图例设置自定义图标?
    easyui datagrid实现拖动表头
    浮动闭合最佳方案:clearfix
    ASP.NET MVC提交LIST列表到后台接收不到数据
    mysql常用命令
  • 原文地址:https://www.cnblogs.com/tqr06/p/11631896.html
Copyright © 2011-2022 走看看