题目链接
Description
Jack helps his mentor build a simple distributed storage system. He uses several servers and connects them as the following topology:
This distributed storage system contains a group of backend servers and a master server. The backend servers are different from each other while they store identical data, and all of them are invisible to client. When a client machine needs a file, it sends request to a master server. The master server collects different part of the file from some of backend servers. The strategy of the master is like follows.
Each backend server has its own processing throughput and transmission bandwidth. The master server knows that ith backend server’s throughput is pi (MB/s) and bandwidth is bi (MB/s). As the result, omitted the propagation time, handling size of fi MB data and sending to master machine needs time:
Total time = Processing time + Transmission time = fi / pi + fi / bi
In addition, handling 1 MB data on ith server costs ci. (Including electricity consumption and maintenance cost, etc.) In order to minimize the total cost, the master server should carefully decide which backends should be used and how much load they should process. At the same time, because of some consistency consideration, every time the master should choose exactly K backend servers to extract file, and each of them should take exactly the same time to finish the job.
Your task is to write a scheduling program for the master server. Assuming the size of the file is F MB, and the file can be infinitely divided.
Input
The first line contains two integers N and K (K≤ N ≤ 20000), and a real number F. The master should choose exactly K machines among total N backend servers. The F is the size of the file.
The following N lines describe the details of each backend servers. Each line contains three real numbers, pi, bi and ci, representing the processing throughput, bandwidth and unit cost.
Output
The output file contains only one real number, the minimum cost. The answer is less than 10000000000 and should be rounded to four digits
Sample Input
3 2 2 1 1 2 1 1 1 2 2 10
Sample Output
3.0000
Hint
In the sample case, the master should choose the first two backend machines. Each of them should handle 1 MB part of the file (total is 2 MB) in order to make the finishing time identically (2 second). The total cost is 1*2+1*1 = 3.0000
这道题来来回回WA了20次了,然后才想起来POJ比较的老了,输出printf("%.4lf")是会返回WA的,WA到自闭才有这样的灵光一现…… 然后在测,就不会WA的那么快了,1A!!!简直了啊!
前面部分就是很基础的01分数规划,找最优解问题,但是一开始的时候以为是线性的,直接二分了时间time是显然错误的。
推理一下:
这里的vi指的是每个电脑处理所花费的时间;
又有对于全体的ti,是相等的,则另ti = t;
不妨令
则有
根据,我们可以知道
我们想用01分数规划去寻找答案的话,过程中就会是一个毕竟的过程,那么,就会使得
则会有
相当于是:
最优解情况当然是" ==0 "情况啊!
然后我们就对上面这个式子去进行01分数规划,二分答案cost即可!!!
千万注意,不要输出"%.4lf",强调用"%.4f"!!!
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-6
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef double lb;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 2e4 + 7;
int N, K;
lb F;
lb l = 0., r = 10000000000., mid = 0., ans = 0.;
struct node
{
lb p, b, c;
node(lb _p = 0, lb _b = 0., lb _c = 0.):p(_p), b(_b), c(_c) {}
lb vi;
void doit() { vi = p * b / (p + b); }
}a[maxN];
bool cmp(node e1, node e2) { return mid * e1.vi - F * e1.vi * e1.c > mid * e2.vi - F * e2.vi * e2.c; }
int main()
{
scanf("%d%d%lf", &N, &K, &F);
for(int i=1; i<=N; i++) { scanf("%lf%lf%lf", &a[i].p, &a[i].b, &a[i].c); a[i].doit(); }
l = 0.; r = 10000000000.; mid = 0.; ans = 10000000000.;
lb sum;
while(r - l >= efs)
{
mid = (l + r) / 2.;
sort(a + 1, a + N + 1, cmp);
sum = 0.;
for(int i=1; i<=K; i++) sum += mid * a[i].vi - F * a[i].vi * a[i].c;
if(sum >= 0)
{
r = mid;
ans = mid;
}
else l = mid;
}
printf("%.4f\n", ans);
return 0;
}