上海市计算机学会竞赛平台第六届上海市青少年算法竞赛网络赛(青年组)文件排序
题目描述
有 nn 份文件需要安置在磁带上,第 ii 份文件的长度为 aiai,它会被访问 cici 次。
当要访问一份文件时,要从磁带上最靠前的文件开始,顺序找到这份文件为止,单次访问的时间就是经过的文件的总长度之和。
你需要在磁带上安排文件的放置顺序,使得所有文件累计访问时间的总和最小。
例如假设磁盘的布局是在第 33 份文件之前还放置了第 11 与第 55 份文件,则
- 单次访问第 33 份文件的时间为 (a1+a5+a3)(a1+a5+a3),
- 累计访问第 33 份文件的时间为 c3(a1+a5+a3)c3(a1+a5+a3)。
输入格式
- 第一行:单个整数表示 nn
- 第二行到第 n+1n+1:每行两个整数 aiai,cici
输出格式
- 单个整数:表示累计访问所有文件的最小总时间。
数据范围
- 30%30% 的数据,1≤n≤101≤n≤10
- 60%60% 的数据,1≤n≤1001≤n≤100
- 100%100% 的数据,1≤n≤100,0001≤n≤100,000
- 1≤ai≤100001≤ai≤10000
- 1≤ci≤100001≤ci≤10000
样例数据
输入:
5
3 5
1 2
4 3
1 4
5 1
输出:
74
说明:
文件4 → 文件2 → 文件1 → 文件3 → 文件5
总时间:4 + 4 + 25 + 27 + 14 = 74
详见代码:
#include <bits/stdc++.h>
using namespace std;
int n;
struct node
{int a, c;
};
node a[100005];
bool cmp(node x, node y)
{return (x.a + y.a) * x.c + y.a * y.c > (x.a + y.a) * y.c + x.a * x.c;
}
long long sum = 0, ans = 0;
int main()
{cin >> n;for(int i = 1; i <= n; i++) {cin >> a[i].a >> a[i].c;}sort(a + 1, a + n + 1, cmp);for(int i = 1; i <= n; i++) {sum += a[i].a;ans += sum * a[i].c;}cout << ans;return 0;
}