zoukankan      html  css  js  c++  java
  • Gym

    题意:给定一棵大小为N的点权树(si,pi),现在让你选敲好K个点,需要满足如果如果u被选了,那么fa[u]一定被选,现在要求他们的平均值(pi之和/si之和)最大。

    思路:均值最大,显然需要01分数规划,但是后面怎么高效的做背包,我是不会的,我只会暴力的背包,O(N*K*K)。 还好队友会,叫“树上依赖背包”,即要问树转化为DFS序,按照倒序来DP,复杂度O(N*K)。dp[i][j]=max(dp[i+1][j-v[x]]+w[x],dp[i+sz[x]][j]),分别对应x选或者不选(其中x是DFS为i的点)。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=2610;
    const double inf=1e20;
    double dp[maxn][maxn],s[maxn],p[maxn],val[maxn];
    int r[maxn],Laxt[maxn],Next[maxn],To[maxn];
    int pos[maxn],tot,cnt,N,K,sz[maxn];
    void add(int u,int v)
    {
        Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
    }
    void dfs(int u)
    {
        sz[u]=1; tot++; pos[tot]=u;
        for(int i=Laxt[u];i;i=Next[i]){
            dfs(To[i]); sz[u]+=sz[To[i]];
        }
    }
    bool check(double Mid)
    {
        rep(i,1,N) val[i]=p[i]-s[i]*Mid;
        rep(i,1,tot+1) rep(j,1,K) dp[i][j]=-inf;
        rep(i,0,tot+1) dp[i][0]=0;
        for(int i=tot;i>=1;i--){
            int x=pos[i];
            for(int j=1;j<=K;j++){
                dp[i][j]=max(dp[i+1][j-1]+val[x],dp[i+sz[x]][j]);
            }
        }
        return dp[1][K]>=0;
    }
    int main()
    {
        scanf("%d%d",&K,&N); K++;
        rep(i,1,N){
            scanf("%lf%lf%d",&s[i],&p[i],&r[i]);
            add(r[i],i);
        }
        dfs(0);
        double L=0,R=10000,Mid,ans=0; int T=30;
        while(T--){
            Mid=(L+R)/2;
            if(check(Mid)) ans=max(Mid,ans),L=Mid;
            else R=Mid;
        }
        printf("%.3lf
    ",ans);
        return 0;
    }
  • 相关阅读:
    Java Web 开发必须掌握的三个技术:Token、Cookie、Session
    $.proxy和$.extend
    手机端和网页端使用同一后台时进行会话控制
    js中使用EL表达式总结
    Durandal入门
    RequireJs入门
    阿里云Prismplayer-Web播放器的使用
    Mac系统实现git命令自动补全
    Mac系统的终端显示git当前分支
    Gulp实现css、js、图片的压缩以及css、js文件的MD5命名
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10548360.html
Copyright © 2011-2022 走看看