Choosing flowers
Problem Description
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 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-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+(xi−1)⋅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 t t ( 1 ≤ t ≤ 10000 1≤t≤10000 1≤t≤10000), the number of test cases. It is followed by 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≤n≤10^9 1≤n≤109, 1 ≤ m ≤ 100000 1≤m≤100000 1≤m≤100000), the number of flowers Vladimir needs to choose and the number of types of available flowers.
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.
Sample Input
2
4 3
5 0
1 4
2 2
5 3
5 2
4 2
3 1
Sample Output
14
16
题意
花店共有m种花,每种花送第一支时有 a i a_i ai的欣赏值,重复送时则有 b i b_i bi的欣赏度,花店每种花的数量是无限的。共想送n支花,求欣赏值的最大值。
题解
对于
b
i
b_i
bi的部分,在送的若干种花中,选择
b
i
b_i
bi最大的即可。
枚举
b
i
b_i
bi,先假设只卖第
i
i
i种花,则和为
a
i
+
(
n
−
1
)
∗
b
i
a_i + (n-1)*b_i
ai+(n−1)∗bi。需要让欣赏值最大,若存在其他的花的
a
j
>
b
i
(
j
!
=
i
)
a_j > b_i(j!=i)
aj>bi(j!=i),则少买一只第
i
i
i种花,买一只第
j
j
j朵花即可。可以考虑对所有种花的
a
a
a值排序,二分快速找出所有大于
b
i
b_i
bi即可。注意需要保留第
i
i
i种的第一支,以及最多找
n
−
1
n-1
n−1个大于
b
i
b_i
bi的其余花种。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100100;
const int mod = 998244353;
struct node{
int a, b;
}p[maxn];
int a[maxn];
LL sum[maxn];
bool cmp(node a, node b);
int main()
{
int t, n, m, i, j, k;
LL ans;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &m);
for(i=1;i<=m;i++)
scanf("%d %d", &p[i].a, &p[i].b);
sort(p+1, p+m+1, cmp);
sum[0] = 0;
for(i=1;i<=m;i++){
a[i] = p[i].a;
sum[i] = sum[i-1]+a[i];
}
a[0] = 0;
ans = 0;
for(i=1;i<=m;i++){
int pos = max(lower_bound(a+1, a+1+m, p[i].b)-a, m-(n-1)+1);
int num = n-1-(m-pos+1);
LL s = p[i].a+1LL*num*p[i].b+sum[m]-sum[pos-1];
if(pos<=m && p[i].a >= a[pos]){
s -= p[i].a;
s += max(p[i].b, a[pos-1]);
}
ans = max(ans, s);
}
printf("%I64d\n", ans);
}
return 0;
}
bool cmp(node a, node b)
{
return a.a < b.a;
}