zoukankan      html  css  js  c++  java
  • [笔记乱写]0/1分数规划

    第一次写这类blog?其实早就想把知识总结一下但是真的没有时间啊喂

    感觉这东西比较实用且简易所以口胡一篇

    所谓分数规划,就是求最优比率,比如一个分数的最大值。

    经典模型:

    给定若干对整数$a_i,b_i$,要求从中选出几对,使$frac{sum a_i}{sum b_i}$最大。

    对于这个问题,我们不妨xjb猜随意选取一个值$L$,然后考虑:

    是否存在一组解,满足$sum a_i-L*b_i ge 0$

    把上面那个鬼畜柿子化一下,可得$sum a_i-sum L*b_i ge 0$,

    最终变成$frac{sum a_i}{sum b_i}ge L$

    那如果符合条件的解存在的话,就说明存在比L更大的比率,即L比我们所求的最大值要小。

    那要是不存在呢?L比最大值还大呗。

    是不是很熟悉?这玩意显然可以二分答案搞吧,因为L与解的关系存在单调性。

    那么怎么判定$sum a_i-L*b_i ge 0$是否有解呢?算一下$sum a_i-L*b_i$的最大值看它正负不就好了。

    这很好求啊,因为$a_i-L*b_i$可以直接算的,只要看一下哪些取哪些不取就能得道最值了。

    所以遇到这类问题直接二分答案,判断$sum a_i-mid*b_i$的最大值是否非负,是就l=mid,否则r=mid(一定要注意实数范围二分与整数二分的不同)

    最后的l就是最优比例。

    丢一道例题[bzoj4753]最优团体

    挺裸的分数规划,不过check需要做树上依赖背包,每次拍成dfs序$O(nK)$dp即可。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=2505;
    const double eps=1e-5,inf=19260817.233;
    int K,n,fa[N];
    double now[N],dp[N][N],w[N],val[N],maxx=-inf;
    int to[N<<1],nxt[N<<1],head[N],tot;
    int dfn[N],rev[N],num,size[N];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    void add(int x,int y)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    void dfs(int x)
    {
        size[x]=1;
        dfn[x]=num;
        rev[num++]=x;
        for(int i=head[x];i;i=nxt[i])
            dfs(to[i]),size[x]+=size[to[i]];
    }
    double DP(double x)
    {
        for(int i=1;i<=n;i++)
            now[i]=val[rev[i]]-x*w[rev[i]];
        for(int i=1;i<=n+1;i++)
            for(int j=0;j<=K+1;j++)
                dp[i][j]=-inf;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=min(i,K+1);j++)
                dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+now[i]),
                dp[i+size[rev[i]]][j]=max(dp[i+size[rev[i]]][j],dp[i][j]);
        return dp[n+1][K+1];
    }
    int main()
    {
        K=read();n=read();
        for(int i=1;i<=n;i++)
        {
            w[i]=(double)read();
            val[i]=(double)read(),maxx=max(maxx,val[i]);
            fa[i]=read();
            add(fa[i],i);
        }
        dfs(0);
        double l=0.0,r=maxx;
        while(r-l>eps)
        {
            double mid=(l+r)/2.0;
            if(DP(mid)>=eps)l=mid;
            else r=mid;
        }
        printf("%.3lf",l);
        return 0;
    }
    View Code
  • 相关阅读:
    HIVE高级(14):优化(14) Hive On Spark配置
    HIVE高级(13):优化(13) Hive Job 优化
    HIVE高级(12):优化(12) 数据倾斜
    HIVE高级(11):优化(11) HQL 语法优化(2) 多表优化
    HIVE高级(10):优化(10) HQL 语法优化(1) 单表优化
    HIVE高级(9):优化(9) Hive 建表优化(1) 分区表/分桶表/合适的文件格式/合适的压缩格式
    HIVE高级(8):优化(8) Explain 查看执行计划(二)
    Hive基础(19):Hive 函数(2) 自定义函数/自定义 UDF 函数/自定义 UDTF 函数
    Hive基础(18):Hive语法(5) DDL(2) 分区表和分桶表
    MATLAB RGB2HSV、HSV2RGB
  • 原文地址:https://www.cnblogs.com/Rorschach-XR/p/11291312.html
Copyright © 2011-2022 走看看