pku 2976 Dropping tests 01分数规划

http://poj.org/problem?id=2976

题意:

给定A数组B数组,从中选择N-K个使得R最大,输出Round(100*R);

思路:

我是根据szz给的这个链接学习的,感觉讲的不错:http://lghjx.573114.com/Blog/Html/103D/275536.html

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a,b) (a) > (b)? (b):(a)

#define Max(a,b) (a) > (b)? (a):(b)



#define ll long long

#define inf 0x7f7f7f7f

#define MOD 1073741824

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 150

#define N 10007

using namespace std;

//freopen("din.txt","r",stdin);



double a[N],b[N],d[N];

const double eps = 1e-6;



int n,k;



int cmp(int a,int b)

{

    return a > b;

}

int dblcmp(double x)

{

    if (x > eps) return 1;

    else if (x < -eps) return -1;

    else return 0;

}

int main()

{

    int i;

    while (~scanf("%d%d",&n,&k))

    {

        if (!n && !k) break;

        for (i = 0; i < n; ++i) scanf("%lf",&a[i]);

        for (i = 0; i < n; ++i) scanf("%lf",&b[i]);

        double r = -1.0;

        for (i = 0; i < n; ++i)

        {

            if (a[i]/b[i] > r) r = a[i]/b[i];

        }

        int m = n - k;

        double l = 0;

        double ans = 0;

        while (dblcmp(l - r) < 0)

        {

            double mid = (l + r)/2.0;

            for (i = 0; i < n; ++i) d[i] = a[i] - mid*b[i];

            sort(d,d + n,cmp);

           // reverse(a,a + n);

            double tmp = 0;

            for (i = 0; i < m; ++i)

            tmp += d[i];

            if (tmp >= 0)

            {

                ans = mid;

                l = mid;

            }

            else r = mid;

        }

        printf("%.0lf\n",ans*100);

    }

    return 0;

}

  

 

你可能感兴趣的:(test)