MT2085 小码哥的福利

思路:

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;
}
  • 22
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值