Codeforces 1379 C Choosing flowers

更好的阅读体验

C. Choosing flowers

开启传送门

题目描述

Vladimir would like to prepare a present for his wife: they have an anniversary! He decided to buy her exactly n n n flowers.

Vladimir went to a flower shop, and he was amazed to see that there are m m m types of flowers being sold there, and there is unlimited supply of flowers of each type. Vladimir wants to choose flowers to maximize the happiness of his wife. He knows that after receiving the first flower of the i i i-th type happiness of his wife increases by a i a_i ai and after receiving each consecutive flower of this type her happiness increases by b i b_i bi. That is, if among the chosen flowers there are x i > 0 x_i>0 xi>0 flowers of type i i i, his wife gets a i + ( x i − 1 ) ∗ b i a_i+(x_i-1)*b_i ai+(xi1)bi additional happiness (and if there are no flowers of type i i i, she gets nothing for this particular type).

Please help Vladimir to choose exactly n n n flowers to maximize the total happiness of his wife.

Input

The first line contains the only integer t ( 1 ≤ t ≤ 10000 ) t (1\le t \le 10000) t(1t10000), the number of test cases. It is followed by t t t descriptions of the test cases.

Each test case description starts with two integers n n n and m m m ( 1 ≤ n ≤ 1 0 9 , 1 ≤ m ≤ 100000 1\le n\le 10^9, 1\le m\le 100000 1n109,1m100000), the number of flowers Vladimir needs to choose and the number of types of available flowers.

The following m m m lines describe the types of flowers: each line contains integers a i a_i ai and b i b_i bi ( 0 ≤ a i , b i ≤ 1 0 9 0\le a_i, b_i\le 10^9 0ai,bi109) for i i i-th available type of flowers.

The test cases are separated by a blank line. It is guaranteed that the sum of values m m m among all test cases does not exceed 100000 100000 100000.

Output

For each test case output a single integer: the maximum total happiness of Vladimir’s wife after choosing exactly n n n flowers optimally.

Example

Input1

2

4 3

5 0

1 4

2 2

5 3

5 2

4 2

3 1

Output1

14

16

Note

In the first example case Vladimir can pick 1 1 1 flower of the first type and 3 3 3 flowers of the second type, in this case the total happiness equals 5 + ( 1 + 2 ⋅ 4 ) = 14 5+(1+2⋅4)=14 5+(1+24)=14.

In the second example Vladimir can pick 2 2 2 flowers of the first type, 2 2 2 flowers of the second type, and 1 1 1 flower of the third type, in this case the total happiness equals ( 5 + 1 ⋅ 2 ) + ( 4 + 1 ⋅ 2 ) + 3 = 16 (5+1⋅2)+(4+1⋅2)+3=16 (5+12)+(4+12)+3=16.

题意

现在有 m m m 种花,每种花都有无线朵,每朵花有两个价值,一个是 首次价值 a i a_i ai, 一个是其他价值 b i b_i bi。如果对于第 i i i 种花,买了 k k k 朵,那么价值为 a i + ( k − 1 ) ∗ b i a_i + (k-1)*b_i ai+(k1)bi。问你如果恰好买 n n n朵花的最大价值。

分析

首先,我们假设所有的 b i b_i bi 都是 0 0 0,那么我们有,我们只需要按照 a i a_i ai 排序,选择 n n n 朵价值最高的,就是答案。

其次,我们是不会选择多个 b i b_i bi 的。这个也很好想,假设选了两个不同的 b i b_i bi b j b_j bj,不妨设 b i > b j b_i > b_j bi>bj,那么我显然可以把额度都用在 b i b_i bi 上,这样价值更高,所以一定只会选择一个 b i b_i bi

然后,一个显而易见的策略就是,我们优先选择几个比较大的 a i a_i ai,然后无脑枚举一个 b i b_i bi,剩下的额度都买这个 b i b_i bi

可以证明,这个一定是个凸函数,所以三分可以得到这个极值。

#include<bits/stdc++.h>
using namespace std;
long long n, m;
pair<long long, long long> num[100010];
bool cmp(pair<long long,long long> a, pair<long long, long long> b) {
	if(a.first != b.first) return a.first>b.first;
	return a.second > b.second;
}
long long cal(int ind) {
	long long ret = 0;
	if(n<ind) return -1;
	for(int i = 1;i<=ind;i++) ret += num[i].first;
	long long ans = 0;
	for(int i = 1;i<=ind;i++) ans = max(ans, num[i].second*(n-ind));
	if(n>ind) for(int i = ind+1;i<=m;i++) ans = max(ans, num[i].second*(n-ind-1) + num[i].first);
	return ret + ans;
}
void solve() {
	cin>>n>>m;
	for(int i = 1;i<=m;i++) cin>>num[i].first>>num[i].second;
	sort(num+1, num+m+1, cmp);
	long long ans = 0;
	int l = 0, r = m;
	while(l+10<r) {
		int lmid = (l*2+r) / 3;
		int rmid = (l+r*2) / 3;
		if(cal(lmid) < cal(rmid)) l = lmid;
		else r = rmid;
	}
	for(int i = l;i<=r;i++) ans = max(ans, cal(i));
	cout<<ans<<endl;
}
int main() {
	int t;
	cin>>t;
	while(t--) solve();
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zuhiul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值