• 【LOJ】#2071. 「JSOI2016」最佳团体


    题解

    01分数规划,二分加树背包……

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define MAXN 2505
    #define mo 999999137
    #define pb push_back
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 + c - '0';
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    
    int K,N,siz[MAXN];
    db S[MAXN],P[MAXN],val[MAXN],dp[MAXN][MAXN],tmp[MAXN];
    struct node {
        int to,next;
    }E[MAXN * 2];
    int head[MAXN],sumE;
    void add(int u,int v) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        head[u] = sumE;
    }
    void Init() {
        read(K);read(N);
        int u;
        for(int i = 2 ; i <= N + 1; ++i) {
            scanf("%lf%lf%d",&S[i],&P[i],&u);++u;
            add(u,i);add(i,u);
        }
        ++N;
    }
    void dfs(int u,int fa) {
        siz[u] = 0;
        dp[u][0] = 0.0;
        for(int i = head[u] ; i ; i = E[i].next) {
            int v = E[i].to;
            if(v != fa) {
                dfs(v,u);
                for(int i = 0 ; i <= siz[u] + siz[v] ; ++i) tmp[i] = -1e9;
                for(int i = 0 ; i <= siz[u] ; ++i) {
                    for(int j = 0 ; j <= siz[v] ; ++j) {
                        tmp[i + j] = max(tmp[i + j],dp[u][i] + dp[v][j]);
                    }
                }
                siz[u] += siz[v];
                for(int i = 0 ; i <= siz[u] ; ++i) dp[u][i] = tmp[i];
            }
        }
        ++siz[u];
        for(int i = siz[u] ; i >= 1 ; --i) {
            dp[u][i] = dp[u][i - 1] + val[u];
        }
    }
    bool check(db mid) {
        for(int i = 1 ; i <= N ; ++i) {
            val[i] = P[i] - S[i] * mid;
        }
        dfs(1,0);
        return dp[1][K + 1] >= 0.0;
    }
    void Solve() {
        db L = 0,R = 1000;
        int cnt = 50;
        while(cnt--) {
            db mid = (L + R) / 2.0;
            if(check(mid)) L = mid;
            else R = mid;
        }
        printf("%.3lf
    ",L);
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Init();
        Solve();
        return 0;
    }
    
  • 相关阅读:
    MySQL基础之排序检索数据
    网络编程之并发网络编程
    网络编程之粘包问题
    MySQL基础之检索数据
    MySQL基础之使用MySQL
    MySQL基础之MySQL简介
    MySQL基础之了解MySQL
    网络编程之socket编程
    网络编程之网络通信原理
    别找了,最全的搜集关键词方法在这里
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9536589.html
Copyright © 2020-2023  润新知