刷题-徒步旅行补给问题-动态规划

85 阅读2分钟

题目连接

www.marscode.cn/practice/8e…

题目

截屏2025-01-05 下午5.14.20.png

解题思路

对于任意天,都存在同样的问题,买 或 不买,买的话,需要买几份。 假如:在第i天,手中还有count份食物,剩余旅程天数为:days = N-i+1 (包含第i天,因为第i天的食物也要在当天购买后食用。);可以做以下分析:

case1: 手中的食物支撑剩下days天的旅程,无需购买。即 count >= days;
case2: 在 i 后面的count天,存在食物价格 小于等于 data[i]的,也无需购买。
case3: 在 i 后面的count天,不存在食物价格 小于等于 data[i]的,需要购买。

当需要购买时,购买量如何计算呢?

当前可购买额度为 quota = k - count;
如果k > days,则 quota = days-a;

判断:在i的后面quota天内,是否存在食物价格 小于等于 data[i]的第q天;
    存在:第i天的购买份额为:q-i-a;
    不存在:第i天的购买份额为:quota。

Java实现

public class Main {
    public static int handle(int i, int count, int n, int k, int[] data) {
        int days = n - i + 1;// 剩余还要走days天。
        if (count >= days) { // 如果剩余的a份食物刚好走完剩下的行程,就不购买食物,直接返回0
            return 0;
        }
        // 如果剩下的食物不够走完全程,基于后面的食品价格判断是否需要购买,以及购买几分。
        // 如果后面的a天中,存在食物价格比今天低,就不购买。
        boolean isExistMin = false;
        for (int j = 0; j < count; j++) {
            if (i + j < data.length && data[i - 1] >= data[i + j]) {
                isExistMin = true;
                break;
            }
        }

        if (count > 0 && isExistMin) {
            return 0;
        }

        int quota = k - count; // 第i天的购买额度
        if (k > days) {
            quota = days - count;
        }

        int num = quota; // 记录第i天的购买量
        for (int j = 0; j < quota - 1; j++) {
            if (data[i + count + j] <= data[i - 1]) {
                num = j + 1;
                break;
            }
        }

        return num;
    }

    public static int solution(int n, int k, int[] data) {
        int count = 0;
        int res = 0;
        for (int i = 1; i <= n; i++) {
            int num = handle(i, count, n, k, data); // 计算出第i天的购买量
            res += num * data[i - 1];
            count += num;
            count--;
        }
        return res;
    }

    public static void main(String[] args) {
        // Add your test cases here

        System.out.println(solution(5, 2, new int[] { 1, 2, 3, 3, 2 }) == 9);
    }
}