Description
佳佳要下载资源,一共t个 每个资源有两个参数
s表示大小,p表示已经下了多少
然后Download Manager,是这样的,一次最多能下n个资源,带宽是b
如果目前比n多,那么就按这种顺序排列
s小的先下
s相同p大的先下
如果目前资源数比n少,那么就一起下
同时下载的资源平分带宽b
问耗时t多少?
Algorithm
首先先排序,生成的下载队列就固定了
然后就是模拟,每次把第一个下载完了移除,然后继续下
然后就TLE了
于是用了双向链表
就A了
Code
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxt = 20000 + 9;
const double kmax_r = 20000+9;
struct V
{
double s;
int p;
double r;
int prev, next;
};
bool cmp(const V &a, const V &b)
{
if (a.s < b.s || (a.s == b.s && a.p > b.p)) return true;
return false;
}
V a[maxt];
int main()
{
int t, n, b;
for (int ii = 1; ;ii++)
{
scanf("%d%d%d", &t, &n, &b);
if (t == 0 && n == 0 && b == 0) break;
for (int i = 1; i <= t; i++)
scanf("%lf%d", &a[i].s, &a[i].p);
sort(a + 1, a + t + 1, cmp);
a[0].next = 1;
for (int i = 1; i <= t; i++)
{
a[i].prev = i - 1;
a[i].next = i + 1;
a[i].r = a[i].s * (100 - a[i].p) * 0.01;
}
a[t + 1].prev = t;
int tt = t;
double ans = 0;
do
{
double r_min = kmax_r;
int p = 0;
for (int i = 0; i < n; i++)
{
p = a[p].next;
if (a[p].r < r_min) r_min = a[p].r;
}
p = 0;
for (int i = 0; i < n; i++)
{
p = a[p].next;
a[p].r -= r_min;
if (a[p].r == 0)
{
a[a[p].prev].next = a[p].next;
a[a[p].next].prev = a[p].prev;
t--;
}
}
ans += (r_min / (double(b) / double(n)));
if (t < n) n = t;
}while (n > 0);
printf("Case %d: %.2lf\n\n", ii, ans);
}
}