力扣135. 分发糖果

题目链接

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
你需要按照以下要求,帮助老师给这些孩子分发糖果:
每个孩子至少分配到 1 个糖果。
评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?

输入:[1,0,2]
输出:5
解释:你可以分别给这三个孩子分发 2、1、2 颗糖果。


分析:
题目的要求就是给每个位置一个数字,满足至少是1且如果当前权值如果大于两侧权值,那当前数字也要大于旁边数字。
就是一个记忆化搜索,从某个点出发,然后向权值更小的方向去搜索,等到搜索不动了,那最后一个一定是1(搜索不动的条件是左右权值都比自己大,只要满足至少是1即可),然后递归回去就知道了出发点的最小权值是多少,如果出发点已经通过别的出发点算出来了就不用算了(在其他出发点的搜索路径上)

class Solution {
    
    
    
    int[] f; // 记录当前点最小权值是多少

    public int candy(int[] ratings) {
    
    
        int n = ratings.length;
        f = new int[n];
        for (int i = 0; i < n; i ++ ) f[i] = -1;
        int res = 0;
        for (int i = 0; i < n; i ++ ) res += dp(i, ratings);
        return res;
    }

    int dp(int u, int[] ratings) {
    
    
        if (f[u] != -1) return f[u]; // 算过了就不要再算了
        f[u] = 1; // 最少是1
        // 要同时满足左右,如果比旁边大,分得的糖果多一个即可
        if (u - 1 >= 0 && ratings[u] > ratings[u - 1]) f[u] = Math.max(f[u], dp(u - 1, ratings) + 1);
        if (u + 1 < ratings.length && ratings[u] > ratings[u + 1]) f[u] = Math.max(f[u], dp(u + 1, ratings) + 1);
        return f[u];
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43795939/article/details/114282424