腾讯机试题3

该博客讨论了一道腾讯的面试题,涉及如何计算在村庄间平衡水果供需的最小运费。文章指出,应当优先考虑满足前面村庄的需求,以降低总成本。通过举例和分析,解释了为何从前向后遍历能得出最优解,并给出了C++代码实现。

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

小Q所以的城镇里有条笔直的公路,在这条公路上分布着n个村庄,编号为1到n。有些村庄需要购进水果,而有些村庄需要贩卖出水果。

设第1个村庄对水果的需求量为Ai其中Ai >0表示该村需要购进水果,Ai <0表示该村需要贩卖出水果。所有村庄供需平衡,即所看Ai之和等于0

把k个单位的水果从一个村庄运到相邻村庄需要k块钱的运费,请你帮助小Q计算一下,最少需要多少运费就可以满足所有村庄对水果的需求。

输入描述:
第一行,整数n, 表示村庄的数量(2<=n<=00000第二行,格间隔的整数, 依次表示1到号村庄对水果的,需求A(-10 Ai<=1000)

输出描述:
一行, 一个整数,表示最小的费用

一、思路

之前的思路应该是有点错误的。

因为是要卖东西,因此只要考虑出售的那一方的距离就好了

考虑如下例子:

10,5,-7,3,-8,-3

显然-7应该卖给5,而不是3,

我们不妨计算一下:
第一种情况:
(1)7
(2)24+7=31
(3)15
第二种情况:
(1)7+2=9
(2)8+15=23
(3)15

显然第二种情况更好,所以在计算时,应该优先满足前面的村庄的需求

再考虑一下这个例子

5,-7,3,-8,-3,10

同样的,也是应该先满足前面的村庄的需求

为什么一定是前面的村庄呢?
其实这和你的遍历方式有关,如果你是从最后一个村庄开始遍历,那么应该优先满足后面的村庄的了

C++代码:

class Solution {
public:
	int minCost(vector<int>& A) {
		int min_cost = 0;
		int next;
		for (int i = 0; i < A.size(); i++) {
			if (A[i] == 0)
				continue;
			// 需要出售水果的村庄
			while (A[i] < 0) {
				next = findMinDistance(i, A);
				if (abs(A[i]) > A[next]) {
					// 还要继续卖
					min_cost += A[next] * (next - i);
					A[i] += A[next];
					A[next] = 0;
				}
				else {
					// 全部售完
					min_cost += abs(A[i])*(next - i);
					A[next] += A[i];
					A[i] = 0;
				}
			}
		}
		return min_cost;
	}
	int findMinDistance(int pos, vector<int>& A) {
		// pos 当前位置
		int min_d = A.size() + 10, min_pos, d;
		for (int i = 0; i < A.size(); i++) {
			if (A[i] > 0) {
				d = abs(i - pos);
				if (d < min_d) {
					min_d = d;
					min_pos = i;
				}
			}
		}
		return min_pos;
	}
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值