小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;
}
};