zoukankan      html  css  js  c++  java
  • P4322 [JSOI2016]最佳团体

    01分数规划+树形dp,其实很好想,题也不难。

    题干:

    题目描述
    
    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 行包含三个整数 SiS_iSi​ , PiP_iPi​ , RiR_iRi​ , 表示候选人 iii 的招募费用,战斗值和推荐人编号。
    
    输出格式:
    
    输出一行一个实数,表示最佳比值。答案保留三位小数。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    const double eps = 1e-4;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 2505;
    struct node
    {
        int l,r,nxt;
    }a[N * 10];
    int len = 0,lst[N],K,n;
    int s[N],p[N];
    db v[N];
    db f[N][N];
    void add(int x,int y)
    {
        a[++len].l = x;
        a[len].r = y;
        a[len].nxt = lst[x];
        lst[x] = len;
    }
    int siz[N];
    db tmp[N];
    void dfs(int x,int fa)
    {
        siz[x] = 1;
        f[x][0] = 0;f[x][1] = v[x];
        for(int k = lst[x];k != -1;k = a[k].nxt)
        {
            int y = a[k].r;
            if(y == fa) continue;
            dfs(y,x);
            duke(j,1,siz[x] + siz[y])
            tmp[j] = f[0][N - 1];
            duke(j,1,siz[x])
                duke(i,0,siz[y])
                    tmp[j + i]=max(tmp[j + i],f[x][j] + f[y][i]);
            siz[x] += siz[y];
            duke(i,1,siz[x])
            f[x][i] = tmp[i];
        }
    }
    int main()
    {
        read(K);read(n);
        memset(lst,-1,sizeof(lst));
        duke(i,1,n)
        {
            int fa;
            read(s[i]);read(p[i]);read(fa);
            add(fa,i);
        }
        db l = 0,r = 10000;
        while(r - l > eps)
        {
            db mid = (l + r) / 2;
            memset(f,0xc2,sizeof(f));
    //        cout<<f[1][1]<<endl;
            duke(i,1,n)
            {
                v[i] = (db)p[i] - (db)mid * s[i];
            }
            dfs(0,0);
            if(f[0][K + 1] > 0) l = mid;
            else r = mid;
        }
        printf("%.3lf",l);
        return 0;
    }
  • 相关阅读:
    洛谷 1850 NOIP2016提高组 换教室
    2018牛客多校第三场 C.Shuffle Cards
    2018牛客多校第一场 B.Symmetric Matrix
    2018牛客多校第一场 A.Monotonic Matrix
    2018牛客多校第一场 D.Two Graphs
    2018宁夏邀请赛L Continuous Intervals
    2018宁夏邀请赛K Vertex Covers
    BZOJ
    HDU
    ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015)
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10425325.html
Copyright © 2011-2022 走看看