列表

详情


NC15574. 小Y做比赛

描述

小Y正在和大家一起参加比赛,比赛共有N道题目,比赛规则是根据做出题目数量来确定排名的,当出题数相同则罚时少的排名在前,一位参赛选手罚时等于他每道做出的题目的罚时之和,做一道题目的罚时等于做出该题目时距离比赛开始后的时间,另外每次错误的提交也会增加罚时。

小Y很厉害,他能做出所有的N道题目,并且不会有提交错误。而对于每道题目,他需要花费一定的读题时间和做题时间,当然他需要读过一道题才能去做那道题。

小Y有一个做题习惯,就是仅当他有两道读过并且还没做出的题时,他才会去做题,并且会选择去做花费做题时间较少的那题。除了只剩一题的情况下,他会去把那题做完。

现在已知这些题目对于小Y的读题时间和做题时间,而小Y的读题顺序是任意的,求小Y最少可能的罚时。(假设小Y在任何情况下都会在比赛时间内做完所有题)

输入描述

第一行是一个正整数,表示题目数量。

接着有N行,每行有两个正整数,分别表示每题的读题时间和做题时间。

输出描述

输出一个正整数,表示小Y的最少罚时。

示例1

输入:

3
1 2
1 3
1 4

输出:

24

说明:

样例1中,先读第一题和第二题,于是会做花时间较少的第一题(4),再读第三题,做第二题(8),最后做第三题(12),罚时4+8+12=24。

示例2

输入:

3
2 3
1 5
3 1

输出:

30

说明:

样例2中,顺序可以为:读第二题->读第三题->做第三题->读第一题->做第一题->做第二题。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 53ms, 内存消耗: 2916K, 提交时间: 2020-03-29 12:09:42

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
const int N=1e5+5;
int a[N],b[N];
P c[N],d[N];
bool vis[N];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&a[i],&b[i]);
		c[i]=P(a[i]+b[i],i);
		d[i]=P(a[i],i);
	}
	sort(c,c+n);
	sort(d,d+n);
	ll ans=(ll)d[0].first*n;
	int last=b[d[0].second];
	vis[d[0].second]=1;
	int p1=0,p2=0;
	for(int i=0;i<n-1;i++)
	{
		while(p1<n&&vis[c[p1].second]) p1++;
		while(p2<n&&vis[d[p2].second]) p2++;
		int t1=a[c[p1].second]+min(last,b[c[p1].second]);
		int t2=a[d[p2].second]+min(last,b[d[p2].second]);
		int p;
		if(t1<=t2) p=c[p1].second;
		else p=d[p2].second;
		vis[p]=1;
		ans+=(ll)(n-i)*(min(t1,t2));
		last=max(last,b[p]);
		
	}
	ans+=last;
	printf("%lld\n",ans);
	return 0;
}

上一题