[USACO22DEC] Cow College B 题解
题目描述
有\(n\)头奶牛,每头奶牛愿意交的最大学费为\(c_i\),问如何设置学费,可以使赚到的钱最多。
\(1\le n\le 10^5,1\le c_i \le 10^6\)
做法分析
首先看数据范围,猜下正解时间复杂度可能是\(O(n \log n)\)。
对于任意学费\(tmp\),设愿意交的学费大于该费用的奶牛为\(num\)个,则现在的收益为\(tmp * num\)。
显然我们将费用设为大于\(tmp\)的最小的一个\(c_x\),获得的总收益显然比现在更优,因为可交费的奶牛不变,但是交的费用\(c_x > tmp\)变大了。
因此我们就可以枚举每个\(c_i\)作为\(tmp\),那现在只需求出大于等于\(c_i\)的个数就行了。
可以从大到小排序,然后枚举每个\(c_i\),那大于等于\(c_i\)的个数就是现在的下标\(i\),也就是求最大的\(c_i * i\)。
注意开long long
还有一个要注意的点是,当有多个解时,要输出学费最小的解。
排序\(O(n \log n)\),遍历\(O(n)\)。
代码
#include<bits/stdc++.h>
#define ll long long
#define MAXn 100010
using namespace std;
int n;
ll a[MAXn], ans = 0, num;
inline bool com(ll a, ll b)
{
return a > b;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
sort(a + 1, a + n + 1, com);
for(int i = 1; i <= n; i++)
{
ll tmp = a[i] * i;
if(tmp >= ans)//注意这里是大于等于
{
ans = tmp;
num = a[i];
}
}
printf("%lld %lld", ans, num);
return 0;
}