zoukankan      html  css  js  c++  java
  • loj #2071. 「JSOI2016」最佳团体

    #2071. 「JSOI2016」最佳团体

     

    题目描述

    JSOI 信息学代表队一共有 NNN 名候选人,这些候选人从 111 到 NNN 编号。方便起见,JYY 的编号是 000 号。每个候选人都由一位编号比他小的候选人 RiR_iRi​​ 推荐。如果 Ri=0R_i=0Ri​​=0,则说明这个候选人是 JYY 自己看上的。

    为了保证团队的和谐,JYY 需要保证,如果招募了候选人 iii,那么候选人 RiR_iRi​​ 也一定需要在团队中。当然了,JYY 自己总是在团队里的。每一个候选人都有一个战斗值 PiP_iPi​​,也有一个招募费用 SiS_iSi​​。JYY 希望招募 KKK 个候选人(JYY 自己不算),组成一个性价比最高的团队。也就是,这 KKK 个被 JYY 选择的候选人的总战斗值与总招募费用的比值最大。

    输入格式

    输入一行包含两个正整数 KKK 和 NNN。
    接下来 NNN 行,其中第 iii 行包含三个整数 Si,Pi,RiS_i,P_i,R_iSi​​,Pi​​,Ri​​ 表示候选人 iii 的招募费用,战斗值和推荐人编号。

    输出格式

    输出一行一个实数,表示最佳比值。答案保留三位小数。

    样例

    样例输入

    1 2
    1000 1 0
    1 1000 1

    样例输出

    0.001

    数据范围与提示

    对于 100%100\%100% 的数据满足 $1≤K≤N≤2500, 0<Si,Pi≤104, 0≤Ri<i1 leq K leq N leq 2500, 0< S_i,P_i leq 10^4, 0 leq R_i<i1KN2500, 0<Si​​,Pi​​104​​, 0Ri​​<i。$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 2510
    #define eps 0.00001
    using namespace std;
    int K,n,head[maxn],num,s[maxn],p[maxn],r[maxn],sz[maxn];
    double w[maxn],f[maxn][maxn];
    struct node{int to,pre;}e[maxn*2];
    void Insert(int from,int to){
        e[++num].to=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    void dfs(int x){
        sz[x]=1;
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            dfs(to);
            sz[x]+=sz[to];
        }
    }
    void dp(int x){
        int tot=0;
        if(x)f[x][1]=w[x],tot=1;
        else f[x][0]=0;
        for(int i=head[x];i;i=e[i].pre){
            int to=e[i].to;
            dp(to);
            tot+=sz[to];
            for(int i=tot;i>=0;i--)
                for(int j=0;j<=sz[to]&&j<=i;j++)
                    f[x][i]=max(f[x][i],f[x][i-j]+f[to][j]);
        }
    }
    bool check(double ans){
        for(int i=1;i<=n;i++)
            w[i]=p[i]-ans*s[i];
        memset(f,0xc2,sizeof(f));
        dp(0);
        return f[0][K]>=0;
    }
    int main(){
        scanf("%d%d",&K,&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&s[i],&p[i],&r[i]);
            Insert(r[i],i);
        }
        dfs(0);
        double l=0,r=10000;
        while(r-l>eps){
            double mid=(r+l)*0.5;
            if(check(mid))l=mid;
            else r=mid;
        }
        printf("%.3lf",(r+l)*0.5);
        return 0;
    }
  • 相关阅读:
    HBase On Spark
    Hive安装配置要点
    通过拆分,提高表的访问效率
    使用冗余统计表
    优化表的数据类型
    以题目为鉴,如何做数学笔记
    思维训练素材整理
    三角函数知识点
    穿针引线法的前世今生
    集合知识点
  • 原文地址:https://www.cnblogs.com/thmyl/p/8872321.html
Copyright © 2011-2022 走看看