• CF739E Gosha is hunting


    法一:

    匹配问题,网络流!

    最大费用最大流,S到A,B流a/b费0,A,B到i流1费p[i]/u[i],同时选择再减p[i]*u[i]?

    连二次!所以i到T流1费0流1费-p[i]*u[i]

    最大流由于ab都选择完最优

    最大费用,所以不会第一次走-p[i]*u[i]

    法二:

    DP怎么写?

    dp[i][j][k]

    优化?

    一定选择a、b个!

    恰好选择a、b个?

    WQS二分!

    一定是满足凸函数的性质的

    所以选择若干个a,代价ca,求dp[i][b]

    再次WQS二分!

    所以选择若干个a,b,代价ca,cb,求dp[i]

    O(nlog^2n)

    卡精度

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define num (ch^'0')
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=num;isdigit(ch=getchar());x=x*10+num);
        (fl==true)&&(x=-x);
    }
    template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
    template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
    ');}
    
    namespace Miracle{
    const int N=2002;
    const double eps=1e-10;
    int numa[N],numb[N];
    int n,a,b;
    double p[N],u[N];
    double dp[N];
    void wrk(double ca,double cb){
        for(reg i=1;i<=n;++i){
            dp[i]=dp[i-1];numa[i]=numa[i-1];numb[i]=numb[i-1];
            if(dp[i]<dp[i-1]+p[i]-ca-eps){
                dp[i]=dp[i-1]+p[i]-ca;numa[i]=numa[i-1]+1;numb[i]=numb[i-1];
            }
            if(dp[i]<dp[i-1]+u[i]-cb-eps){
                dp[i]=dp[i-1]+u[i]-cb;numb[i]=numb[i-1]+1;numa[i]=numa[i-1];
            }
            if(dp[i]<dp[i-1]+u[i]+p[i]-p[i]*u[i]-ca-cb-eps){
                dp[i]=dp[i-1]+u[i]+p[i]-p[i]*u[i]-ca-cb;numb[i]=numb[i-1]+1;numa[i]=numa[i-1]+1;
            }
        }
    }
    double che(double ca){
        double l=0,r=1;
        for(reg i=1;i<=50;++i){
            double mid=(l+r)/2;
            wrk(ca,mid);
            if(numb[n]>b){
                l=mid;
            }else{
                r=mid;
            }
        }
        return (l+r)/2;
    }
    int main(){
        rd(n);rd(a);rd(b);
        for(reg i=1;i<=n;++i){
            scanf("%lf",&p[i]);
        }
        for(reg i=1;i<=n;++i){
            scanf("%lf",&u[i]);
        }
        double l=0,r=1,ka,kb;
        for(reg i=1;i<=50;++i){
            double mid=(l+r)/2;
            kb=che(mid);
            if(numa[n]>a){
                l=mid;
            }else{
                r=mid;
            }
        }
        ka=(l+r)/2;
        wrk(ka,kb);
        printf("%.10lf",dp[n]+ka*a+kb*b);
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/3/22 20:22:58
    */

    巧妙之处:虽然不是恰好选择,但是选择a,b个一定是最优的!(就算是区间,也可以区间WQS二分)

  • 相关阅读:
    JDK8中的 Lambda 表达式
    IDEA导入新项目jar包以及项目依赖tomcat设置
    idea导入项目,类为灰色,左下角有个红圈
    mysql服务忽然挂了,出现错误信息: Can’t connect to MySQL server on ‘localhost’ (10061)
    mysql、oracle、sql server连接信息
    mybatis中select * 中有字段,自己在起一个别名,然后实体类会使用哪个?
    pymongo的操作
    mongodb备份恢复
    mongodb建立索引
    mongodb聚合命令
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10581022.html
Copyright © 2020-2023  润新知