华为OD题目: 贪心的商人
输入描述:
3 //输入商品的数量 number
3 // 输入商人售货天数 days
4 5 6 //输入仓库限制每件商品的最大持有数量是itemlindex]
1 23 // 输入第一件商品每天的价格
4 32 // 输入第二件商品每天的价格
1 53 // 输入第三件商品每天的价格
输出描述:
32//输出商人在这段时间内的最大利润
补充说明:
根据输入的信息:
number = 3
days = 3
item[3] = 14,5,6
item pricel[3][4] = f1, 2,3, 4,3,2,1,5,3
针对第一件商品,商人在第一天的价格是item pricel0J0 = 1时买入item01件,在第三天item price0]2 = 3的时候卖出,获利最大是8:
针对第二件商品,不进行交易,获利最大是0:
针对第三件商品,商人在第一天的价格是item price[2][0] = 时买入item[2)件,在第二天item pricel2]0 == 5的时候卖出,获利最
大是24;
因此这段时间商人能获取的最大利润是8 + 24 = 32:
示例1
输入:
3
3
4 5 6
1 2 3
4 3 2
1 5 3
输出:
32
示例2
输入:
1
1
1
1
输出:
0
解题思路:
- 贪心算法, 和leetcode 122.买卖股票的最佳时机II 基本差不多
- 贪心算法
- 这道题目可能我们只会想,选一个低的买入,再选个高的卖,再选一个低的买入…循环反复。
- 如果想到其实最终利润是可以分解的,那么本题就很容易了!
- 如何分解呢?
- 假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]。
- 相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。
- 此时就是把利润分解为每天为单位的维度,而不是从0天到第3天整体去考虑!
- 那么根据prices可以得到每天的利润序列:(prices[i] - prices[i - 1])…(prices[1] - prices[0])。
import java.util.*;
public class My {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String numberStr = sc.nextLine();
String daysStr = sc.nextLine();
int num = Integer.parseInt(numberStr);
int days = Integer.parseInt(daysStr);
String itemsStr = sc.nextLine();
String[] strings = itemsStr.split(" ");
int[] items = new int[strings.length];
for (int i = 0; i < items.length; i++) {
items[i] = Integer.parseInt(strings[i]);
}
int sum = 0;
for (int i = 0; i < num; i++) {
String priceArrStr = sc.nextLine();
String[] priceArr = priceArrStr.split(" ");
int maxProfit = 0;
//下面使用贪心的算法,计算每件商品的最大利润
for (int j = 1; j < priceArr.length; j++) {
int cur = Integer.parseInt(priceArr[j]);
int pre = Integer.parseInt(priceArr[j-1]);
//当天价格-前一天价格,如果当天利润大于0,则卖出,否则保存
int curProfit = cur - pre;
maxProfit += Math.max(curProfit, 0);
}
sum += maxProfit * items[i];
}
System.out.println(sum);
}
}