• POJ 2976 01分数规划


    题意:

     给定n个二元组(a,b),删除k个二元组,使得剩下的a元素之和与b元素之和的比率最大(比率最后乘100输出)

    题解:

    最裸的01分数规划,以此题为例讲述如何构造。

    设:xi∈{0,1},表示第i个二元组是否留下,p为比率,P为p的最大值,即比例的最大值(注意区分大P于小p)

    则:p=sigma(ai*xi)/sigma(bi*xi)   其中sigma(xi)=n-k

    显然:对于所有可能的取得的 p 的值,p<=P

    即:对于所有可能的xi的组合,sigma(ai*xi)/sigma(bi*xi)<=P

    即:sigma(ai*xi)/sigma(bi*xi)的最大值等于P

    即:sigma(ai*xi)-sigma(P*bi*xi)<=0,也就是sigma(ai*xi)-sigma(P*bi*xi)的最大值等于0

    由于:sigma(ai*xi)-sigma(p*bi*xi)等价于sigma((ai-bi*p)*xi),sigma((ai-bi*P)*xi)的最大值就等于0

    同理:

    设:我们枚举的p的最大值为m(对于虽有的xi的组合,不一定存在m这个取值)

    若m>P,sigma((ai-bi*P)*xi)的最大值小于0

    若m<P,sigma((ai-bi*P)*xi)的最大值大于0

    然后通过二分逼近的方法可以求出m=P~

    市面上能够见到的01分数规划大都就是这么做~

    View Code
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <algorithm>
     6 
     7 #define N 1100
     8 
     9 using namespace std;
    10 
    11 struct PX
    12 {
    13     double a,b,c;
    14 }px[N];
    15 
    16 int n,p;
    17 double l,r,mid;
    18 
    19 inline bool cmp(const PX &a,const PX &b)
    20 {
    21     return a.c>b.c;
    22 } 
    23 
    24 inline void read()
    25 {
    26     for(int i=1;i<=n;i++) scanf("%lf",&px[i].a);
    27     for(int i=1;i<=n;i++) scanf("%lf",&px[i].b);
    28 }
    29 
    30 inline bool check()
    31 {
    32     for(int i=1;i<=n;i++)
    33         px[i].c=px[i].a-px[i].b*mid;
    34     sort(px+1,px+1+n,cmp);
    35     double ans=0.0;
    36     for(int i=1;i<=n-p;i++) ans+=px[i].c;
    37     if(ans<0.0) return true;
    38     else return false;
    39 }
    40 
    41 inline void go()
    42 {
    43     l=0.0; r=1.0;
    44     while(r-l>1e-8)
    45     {
    46         mid=(l+r)/2.0;
    47         if(check()) 
    48             r=mid;
    49         else l=mid;
    50     }
    51     printf("%.0lf\n",mid*100);
    52 }
    53 
    54 int main()
    55 {
    56     while(scanf("%d%d",&n,&p),n||p) read(),go();
    57     return 0;
    58 } 
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    硬件的快速迭代开发
    DAC8775芯片的使用
    单片机引脚复用使用不当会导致bug
    单片机为32bit时运算中64bit运算中遇到的bug及其规避手段
    UDS文档的阅读
    DAC124S085芯片的使用
    LSD低边驱动芯片的特点
    小时候的玩具激光灯拆解
    飞思卡尔系列单片机的censorship的使用
    TypeScript学习小结
  • 原文地址:https://www.cnblogs.com/proverbs/p/2853725.html
Copyright © 2020-2023  润新知