zoukankan      html  css  js  c++  java
  • [二分][dp] Jzoj P3454 表白(love)

    Description

    鸡腿是CZYZ的著名DS,但是不想追妹子的DS不是好GFS,所以鸡腿想通过表白来达到他追到妹子的目的!虽然你对鸡腿很无语,但是故事的设定是你帮助鸡腿找到了妹子,所以现在你必须帮助鸡腿安排表白来实现故事的结局 ! 

    鸡腿想到了一个很高(sha)明(bi)的做法,那就是去找人来组成表白队伍来增强气势 !鸡腿有很多好基友来帮忙,鸡腿数了数一共有N个人。但是鸡腿觉得大家排成两队来比较好看,而且鸡腿经过计算,第一队N1个人,第二队N2个人是最佳的队伍。问题来了...有些好基友们虽然很好心但是可能造成不好的影响(形象猥琐),所以鸡腿就给每个人打了分。Q1i表示第i个好基友排到第一队里时的好影响,C1i表示第i个好基友排到第一队里时的不良影响,Q2i表示第i个好基友排到第二队里时的好影响,C2i表示第i个好基友排到第二队里时的不良影响。请给鸡腿一种安排使得Q的和与C的和的比值最大,给出最大值。 
     

    Input

    第一行给出三个整数N、N1、N2。 

    第2到N+1行,每行四个整数Q1,C1,Q2,C2。 

    Output

    一行输出一个小数d表示最优化比例是d(保留6位小数) 
     

    Sample Input

    5 2 2
    12 5 8 3
    9 4 9 4
    7 3 16 6
    11 5 7 5
    18 10 6 3

    Sample Output

    2.444444
     

    Data Constraint

    对于50%的数据0 < N1 + N2 ≤ N ≤ 50; 

    对于100%的数据0 < N1 + N2 ≤ N ≤ 500,1 ≤ Q1, Q2 ≤ 2000,1 ≤ C1, C2 ≤ 50。

    题解

    • 答案:ΣQ1[i]+ΣQ2[i]/ΣC1[i]+ΣC2[i]
    • 设当前比例x
    • 则有Σ(Q1[i]-C1[i]*x)+Σ(Q2[i]-C2[i]*x)>=0
    • 设a[i]为(Q1[i]-C1[i]*x)-(Q2[i]-C2[i]*x)
    • 这样的话我们只用判断 最后 两边 取的人 的a 的和>=0
    • 考虑二分x,恶心的精度!!!
    • 可以用DP来判断二分的合法性
    • 设f[i][j]、k[i][j]为前i个人取j个人的a的和
    • 先按a数组从大到小排序
    • 那么第一队列要选最优的肯定在前面,第二队肯定在后面
    • 第一队从前往后取,第二队从后往前取

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const double e=0.000000001;
     8 struct edge{ double x,y,v; }k[510];
     9 int Q1[510],Q2[510],C1[510],C2[510],n1,n2,n;
    10 double f[510][510],z[510][510],l,r,mid;
    11 bool cmp(edge x,edge y) { return x.v>y.v; }
    12 bool pd(double x)
    13 {
    14     for (int i=1;i<=n;i++)
    15     {
    16         k[i].x=Q1[i]-C1[i]*x;
    17         k[i].y=Q2[i]-C2[i]*x;
    18         k[i].v=k[i].x-k[i].y;
    19     }
    20     sort(k+1,k+n+1,cmp);
    21     memset(f,200,sizeof(f));
    22     memset(z,200,sizeof(z));
    23     f[0][0]=0;
    24     for (int i=1;i<=n;i++)
    25     {
    26         f[i][0]=0;
    27         for (int j=1;j<=min(n1,i);j++) f[i][j]=max(f[i-1][j],f[i-1][j-1]+k[i].x);
    28     }    
    29     z[0][0]=0;
    30     for (int i=n;i>=1;i--)
    31     {
    32         z[n-i+1][0]=0;
    33         for (int j=1;j<=min(n2,n-i+1);j++) z[n-i+1][j]=max(z[n-i][j],z[n-i][j-1]+k[i].y);
    34     }
    35     for (int i=n1;i<=n-n2;i++) if (f[i][n1]+z[n-i][n2]>=0) return true; 
    36     return false;
    37 }
    38 int main()
    39 {
    40     //freopen("love.in","r",stdin);
    41     //freopen("love.out","w",stdout);
    42     scanf("%d%d%d",&n,&n1,&n2);
    43     for (int i=1;i<=n;i++) scanf("%d%d%d%d",&Q1[i],&C1[i],&Q2[i],&C2[i]);
    44     l=0.01; r=2000;
    45     while (l+e<r)
    46     {
    47         mid=(l+r)/2;
    48         if (pd(mid)) l=mid; else r=mid-e;
    49     }
    50     printf("%.6f",l);
    51     return 0;
    52 }
  • 相关阅读:
    读书笔记之理想设计的特征
    一些javascript 变量声明的 疑惑
    LINQ 使用方法
    Google MySQL tool releases
    读书笔记之设计的层次
    EF之数据库连接问题The specified named connection is either not found in the configuration, not intended to be used with the Ent
    转载 什么是闭包
    javascript面向对象起步
    Tips
    数据结构在游戏中的应用
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9274007.html
Copyright © 2011-2022 走看看