欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

wyh的物品(01分数规划)

程序员文章站 2022-05-21 19:59:42
...

wyh的物品(01分数规划)

思路:有题可知最后的答案ans满足

ans=i=1mvi/i=1mwi ans= \sum_{i=1}^mv_i /\sum_{i=1}^mw_i
上面变形为
i=1mviansi=1mwi>=0 \sum_{i=1}^mv_i-ans*\sum_{i=1}^mw_i>=0

由上可知我们可以二分答案ans检测其正确性

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define space putchar(' ')
#define enter putchar('\n')
#define ZY set<node>::iterator
#define lson root<<1
#define rson root<<1|1
const int MOD7 = 1e9 + 7;
const int MOD9 = 1e9 + 9;
const int imax_n = 1e5 + 7;
typedef pair<int,int> PII;
const int inf=0x3f3f3f3f;
//const int mod=1e9+7;
const int N=5e6+10;
const double esp=1e-10;


ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}

ll lcm(ll a,ll b)
{
    return a*(b/gcd(a,b));
}

template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-')
            op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op)
        x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0)
        x = -x, putchar('-');
    if(x >= 10)
        write(x / 10);
    putchar('0' + x % 10);
}

double a[N],b[N],c[N];
int main()
{
   int t;
   int n,k;
   read(t);
   while(t--)
   {
       read(n),read(k);
       for(int i=1;i<=n;i++)
       {
           read(a[i]),read(b[i]);
       }
       double l=0,r=10000000.0;
       while(r-l>esp)
       {
           double mid=(l+r)/2.0;
           for(int i=1;i<=n;i++)
            c[i]=1.0*b[i]-1.0*mid*a[i];
           sort(c+1,c+1+n,greater<double>());
           double sum=0.0;
           for(int i=1;i<=k;i++)
           {
               sum+=1.0*c[i];
           }
           if(sum>=0.0)l=mid;
           else r=mid;

       }
       printf("%.2f\n",l);


   }




    return 0;
}

相关标签: 二分