这就是astar比赛时当初失误把List[i][j]下标写反了的那个题目,很可惜 这个问题的原理可以用这个数学不等式表示,那就是 a,b,c,d均为正整数,那么由 a/b > c/d 可以推出 a/b > (a+c)/(b+d) > c/d 传输方案规划 (30分) 问题背景 面对艰巨复杂的技术挑战,百度所崇尚的系统设计哲学是“简单可依赖”,而百度的工程师们正在互联网世界中实践着这种理念。这里正好有一个挑战,让作为百度之星的你小试牛刀: 在处理数以百亿计的网络信息的过程中,有一个很常见的问题: 怎么样将一个集群上的信息以最低的成本传输到另外一个集群上? * 数据源集群A有n台服务器,编号为 1, 2, ..., n,i号服务器上待传输的数据量为Ai ,单位是GB。 * 目的地集群B有m台服务器,编号为 1, 2, ..., m,j号服务器上的空闲容量为 Bj,单位为 GB。 * A集群的i号服务器上的每GB数据对于B的集群的j号服务器收益为Vi,j,从 A 集群的 i 号服务器向 B 集群的 j 号服务器传输 1GB数据的开销为Ci,j。 你的任务是在保证A中的所有数据传输完毕的前提下,性价比V/C尽量高。其中V为所有数据在B集群上的价值之和,C为总开销。换句话说,若A集群的i号服务器向B集群的j号服务器发送了Ti,j个GB的数据(Ti,j不一定是整数),则性价比定义为: 输入格式 第1行两个整数n, m(1<=n,m<=50),即集群A和B各自的服务器台数。 第2行包含n个不超过100的正整数A1,A2,…,An,即集群A中每台服务器的待传输数据量(单位:GB)。 第3行包含m个不超过100的正整数B1,B2,…,Bm,即集群B中每台服务器所能接受的最大数据量(单位:GB)。 第 4 ~ n+3 行每行包含m个不超过100的非负整数Vi,j,表示集群A的i号服务器中每GB数据对于集群B中的j号服务器的价值。 第 n+4 ~ 2n+3 行每行包含m个不超过100的正整数Ci,j,表示集群A的i号服务器中每GB数据传输到集群B中的j号服务器所需要的开销。 输出格式 仅一行,为最大性价比。输出保留三位小数(四舍五入)。如果A的数据无法传输完毕,输出字符串 “-1”(无引号)。 样例输入 2 2 1 2 2 1 11 0 7 5 6 1 3 2 样例输出 2.091 样例解释 一个方案是: 集群A的1号服务器把所有数据传输到集群B的1号服务器,价值11,开销6。 集群A的2号服务器把1GB数据传输到集群B的1号服务器,价值7,开销3,然后把剩下的1GB数据传输到集群B的2号服务器,价值5,开销2。 性价比:(11+7+5)/(6+3+2)=2.091 另一个方案是: 集群A的1号服务器把所有数据传输到集群B的2号服务器,价值0,开销1。 集群A的2号服务器把所有数据传输到集群B的1号服务器,价值14,开销6。 性价比:(0+14)/(1+6)=2。 第一种方案更优。
#include <iostream>
#include <cstdio>
using namespace std;
// A,B 群台数
int N;
int M;
// A,B 群各机器容量
int A_CON[51];
int B_CON[51];
// 总收益,总开销
int totalV;
int totalC;
//
int totaltransferGB;
pair<int, int> List[51][51];
void transfer_onetime()
{
int i,j;
float vc;
float maxvc = 0;
int maxvcAi, maxvcBj;
int found = 0;
for (i = 1; i <= N ; i++)
{
if (found) break;
if (A_CON[i] == 0) continue;
for (j = 1; j <= M ; j++)
{
if (B_CON[j] == 0) continue;
// 如果开销为0则为最大传输
if (List[i][j].second == 0)
{
maxvcAi = i;
maxvcBj = j;
found = 1;
break;
}
vc = (float)List[i][j].first/(float)List[i][j].second;
if (vc >= maxvc)
{
maxvc = vc;
maxvcAi = i;
maxvcBj = j;
}
}
}
//
int transferGB = A_CON[maxvcAi]>B_CON[maxvcBj]?B_CON[maxvcBj]:A_CON[maxvcAi];
A_CON[maxvcAi] -= transferGB;
B_CON[maxvcBj] -= transferGB;
totalV += transferGB * List[maxvcAi][maxvcBj].first;
totalC += transferGB * List[maxvcAi][maxvcBj].second;
totaltransferGB += transferGB;
}
int main2(int argc, int argv[])
{
freopen("t3.in", "r", stdin);
scanf("%d%d", &N, &M);
// 集群A中每台服务器的待传输数据量
int i = 1;
while( i <= N )
{
scanf("%d", &A_CON[i]);
i++;
}
// 集群B中每台服务器所能接受的最大数据量
i = 1;
while( i <= M )
{
scanf("%d", &B_CON[i]);
i++;
}
// 集群A的i号服务器中每GB数据对于集群B中的j号服务器的价值
int j;
for (i = 1; i <= N ; i++)
for (j = 1; j <= M ; j++)
scanf("%d", &List[i][j].first);
// 集群A的i号服务器中每GB数据传输到集群B中的j号服务器所需要的开销
for (i = 1; i <= N ; i++)
for (j = 1; j <= M ; j++)
scanf("%d", &List[i][j].second);
// 判断是否可以可以传输完毕
int totalA = 0;
int totalB = 0;
for (i = 1 ; i <= N; i++)
totalA += A_CON[i];
for (i = 1 ; i <= N; i++)
totalB += B_CON[i];
if (totalA > totalB)
{
printf("-1/n");
return 0;
}
totalV = 0;
totalC = 0;
totaltransferGB = 0;
// 每轮传输一次最大VC的数据
while (totaltransferGB < totalA)
{
transfer_onetime();
}
printf("%0.3f/n", (float)totalV/(float)totalC);
return 0;
}