135. 分发糖果

法一:记忆化搜索,找最长下降路径

class Solution {
public:
    int dp(int x, vector<int>&ratings, vector<int>& f){
        if(~f[x])return f[x];
        int a = x - 1, b = x + 1, n = ratings.size();f[x] = 1;
        if(a >= 0 && ratings[a] < ratings[x])f[x] = max(dp(a,ratings,f) + 1, f[x]);
        if(b < n && ratings[b] < ratings[x])f[x] = max(dp(b,ratings,f) + 1, f[x]);
        return f[x];
    }
    int candy(vector<int>& ratings) {
        int n = ratings.size(), res = 0;
        vector<int>f(n + 1, -1);
        for(int i = 0; i < n; ++i)res += dp(i, ratings, f);
        return res;
    }
};

法2:贪心

​ 从左至右求出满足规则:当ratings[i - 1] < ratings[i]candy[i]大于candy[i - 1]的分配方案l[N];

​ 从右至左求出满足规则:当ratings[i + 1] < ratings[i]candy[i]大于candy[i + 1]的分配方案r[N];

​ 符合条件的分配方案要求满足上述两个规则,每项取\(max\)求和即可。

class Solution {
public:
    int candy(vector<int>& ratings) {
        int n = ratings.size(), res = 0;
        vector<int>l(n, 1), r(n, 1);
        for(int i = 1; i < n; ++i) 
            if(ratings[i] > ratings[i - 1]) 
                l[i] = l[i - 1] + 1;
        for(int i = n - 2; i >= 0; --i) 
            if(ratings[i] > ratings[i + 1]) 
                r[i] = r[i + 1] + 1;
        for(int i = 0; i < n; ++i) res += max(l[i], r[i]);
        return res;
    }
};