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