小P当志愿者送餐 ZZULIOJ - 1361 贪心 模拟

本文通过一个具体的样例,解析了一种基于贪心策略的路径供应问题解决方案。问题核心在于,在固定代价下,如何优化路径以最小化总成本。文章详细阐述了为何应优先考虑满足路径末端的需求,并通过代码实现进一步解释了这一策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题解

题目说了,最终的答案只和走的路径长度有关,交付的代价是固定的。
拿最后一个样例说明,最大携带量为10,三个点需求分别为5 0 8,如果最先满足第一个点5则还有剩余物品,有两个选择要么是继续向后走,要么是回起点重新补充。
继续向后走剩余的5个对于8个来说还不能满足,则需要再走一趟到最后一个点,这样代价就会高。
如果选择会起点补充则相当于浪费了5个物品,对于这个样例来说不会亏但是肯定也不会赚。
则贪心思路为尽量先供应最后面的点,接受的时候使用一个p记录最后的点再那个位置,每次行走代价就是p*30(来回一趟),如果当前点供应完毕则令p–向前移动。
具体看代码,备注比较详细。

AC代码

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 100;
int a[N];

int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	int T;
	cin >> T;
	while (T--)
	{
		int m, n, p = 0; //p最后一个有效点
		scanf("%d%d", &m, &n);
		ll ans = 0;
		for (int i = 1; i <= n; ++i)
		{
			scanf("%d", &a[i]);
			if (a[i])
				p = i;
		}
		while (p)
		{
			ans += p * 30; //到p再回原点代价
			int t = m; //身上所带物品
			while (p && t)
			{
				int e = min(t, a[p]); //交付
				t -= e;
				a[p] -= e;
				ans += e * 3; //交付代价
				while (p && !a[p]) //如果当前点已经送完则移动p
					p--;
			}
		}
		printf("%lld\n", ans);
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值