題目是POJ3757。
開始看題感覺頭疼的地方是要求同時完成。這里有一個很精髓的轉(zhuǎn)換,把流量換為速度。假設(shè)最終時間為t,那么對于每個被選中的服務(wù)器,速度vi=fi/t=bp/(b+p),兩邊求和t=sigma(fi)/sigma(vi)=F/sigma(vi),然后最后要求總花費(fèi)最小,每個被選中的服務(wù)器的花費(fèi)為fi*ci=vi*ti*ci。兩個式子有可以推出對于選出的K個服務(wù)器,
sigma(vi*ti)=sigma(fi)=F,sigma(fi*ci)=sigma(vi*ti*ci),將ti=F/sigma(vi)帶入式子。總花費(fèi)cost=F*sigma(vi*ci)/sigma(vi),這樣就轉(zhuǎn)換成了標(biāo)準(zhǔn)的分?jǐn)?shù)規(guī)劃了~
1
#include <iostream>2
#include <cstdio>3
#include <algorithm>4
#include <cstring>5
#include <cmath>6
using namespace std;7

8
int N,K;9
double F,ans;10

11

struct Sever
{12
double pi,bi,ci,xi,vi,value;13

bool operator < (const Sever &A) const
{14
return value<A.value;15
}16
}sever[20005];17

18

bool bigger(double mid)
{19
int i;20

for(i=0;i<N;i++)
{21
sever[i].value=F*sever[i].xi-mid*sever[i].vi;22
}23
sort(sever,sever+N);24
double sum=0;25

for(i=0;i<K;i++)
{26
sum+=sever[i].value;27
}28
if(sum<0) return true;29
return false;30
}31

32

int main()
{33
scanf("%d%d",&N,&K);34
scanf("%lf",&F);35
int i;36

for(i=0;i<N;i++)
{37
scanf("%lf%lf%lf",&sever[i].pi,&sever[i].bi,&sever[i].ci);38
sever[i].vi=sever[i].bi*sever[i].pi/(sever[i].pi+sever[i].bi);39
sever[i].xi=sever[i].vi*sever[i].ci;40
}41
double l=0.0,r=1e10+1,mid;42

while(r-l>1e-5)
{43
mid=(l+r)/2;44

if(bigger(mid))
{45
r=mid;46
}47

else
{48
l=mid;49
}50
}51
printf("%.4lf\n",mid);52
return 0;53
}54


