思路:
1. 耐受度从小到大排序,每一个甜品都找到第一个能忍受其甜度的手下。
例如样例:甜度为1的2份甜品给第1个人吃(此人耐受为2);甜度为3的9份甜品给第2个人吃(此人耐受为3);甜度为4的4份甜品给第3个人吃(此人耐受为5);
将sum[]数组赋值为[2,9,4],之后将其平均化:甜品的转移只能从左到右转移,即第2个人吃的9个甜品只能分给右边的第3个人。
2. 每一次都想达到一个理论上的平均值,所以从第1 个人开始遍历,每一次遍历都计算i到n的平均。如果此人大于平均,则需要将甜品转移给右边的人
例如样例:遍历1号时,平均=(2+9+4)/3=5,1号此时为2,所以不用处理;遍历2号时,平均=(9+4)/2=6.5=6,2号此时为9,所以把3个甜品分给右边的3号。最后sum[]=[2,6,7]。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 55;
ll n, m, a[N], sum[N];
struct tianpin
{
ll b, c;
} t[N];
int cmp(tianpin x, tianpin y)
{ // 甜品甜度由小到大排序
return x.b < y.b;
}
ll add(int l, int r)
{ // 计算sum[l]到sum[r]的和
ll ans = 0;
for (int i = l; i <= r; i++)
{
ans += sum[i];
}
return ans;
}
int main()
{
cin >> n;
ll maxn = 0; // 最高耐受度
for (int i = 1; i <= n; i++)
{
cin >> a[i];
maxn = max(maxn, a[i]);
}
sort(a + 1, a + n + 1);
cin >> m;
for (int i = 1; i <= m; i++)
{
cin >> t[i].b;
if (t[i].b > maxn) // 此甜品没有能容忍的人
{
cout << -1 << endl;
return 0;
}
}
for (int i = 1; i <= m; i++)
{
cin >> t[i].c;
}
sort(t + 1, t + n + 1, cmp);
for (int i = 1; i <= m; i++)
{ // sum数组赋初值,每个甜品找第一个能吃的人
for (int j = 1; j <= n; j++)
{
if (a[j] >= t[i].b)
{
sum[j] += t[i].c;
break;
}
}
}
for (int i = 1; i <= n; i++)
{ // 平均化
ll tmp = (add(i, n)) / (n - i + 1);
if (tmp <= sum[i])
{ // 此人分配的甜品过多->分给右边的人
sum[i + 1] += sum[i] - tmp;
sum[i] = tmp;
}
}
ll ans = 0;
for (int i = 1; i <= n; i++)
{
ans = max(ans, sum[i]);
}
cout << ans << endl;
return 0;
}