POJ3757 01分数规划

题意:
     有一个任务,给你提供n太服务器,让你在这n太服务器中选出k台完成这个任务,要求是每台服务器的工作时间相同,总的花费最小。

思路:
     题目中给出对于每台服务器有这个式子:
Total time = Processing time + Transmission time = fi / pi + fi / bi
转化后是: time = fi * (pi + bi) / (pi * bi) 那么也就是说每台服务器的工作速度是
v[i] = (pi * bi) / (pi + bi)
因为所有工作时间是一样的,那么就会有 t = F / sigma(v[i])  (选出K个的)
则总的花费就是 
COST = sigma(fi * c[i])
     = sigma(v[i] * t * c[i])
     = t * sigma(v[i] * c[i])  
     = F / sigma(v[i]) * sigma(v[i] * c[i])
     = F * sigma(v[i] * c[i]) / sigma(v[i])
     = sigma(F * v[i] * c[i]) / sigma(v[i])

这样就满足了01分数规划的要求模式了,直接二分就ok了,这个题目注意点精度问题,还有就是二分的上线开大点。


#include<stdio.h>
#include<algorithm>

#define eps 0.000001

#define N 200000 + 100

using namespace std;

double X[N];
double V[N];
double D[N];

bool OK(double L ,int n ,int k)
{
   for(int i = 1 ;i <= n ;i ++)
   D[i] = X[i] - L * V[i];
   sort(D + 1 ,D + n + 1);
   double sum = 0;
   for(int i = 1 ;i <= k ;i ++)
   sum += D[i];
   return sum <= 0;
}


int main ()
{
   int n ,k;
   double f ,p ,b ,c;
   while(~scanf("%d %d %lf" ,&n ,&k ,&f))
   {
      for(int i = 1 ;i <= n ;i ++)
      {
         scanf("%lf %lf %lf" ,&p ,&b ,&c);
         V[i] = p * b / (p + b);
         X[i] = V[i] * c * f;
      }
      double low = 0 ,up = 10000000000;
                           
      double mid ,ans;
      while(up - low >= eps)
      {
         mid = (low + up) / 2;
         if(OK(mid ,n ,k))
         ans = up = mid;
         else  low = mid;
      }
      printf("%.4lf\n" ,ans);
   }
   return 0;
}
      

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值