There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
Each child must have at least one candy.
Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
典型的贪心算法题本身可以用贪心法来做,我们用candy[n]表示每个孩子的糖果数,遍历过程中,如果孩子i+1的rate大于孩子i 的rate,那么当前最好的选择自然是:给孩子i+1的糖果数=给孩子i的糖果数+1如果孩子i+1的rate小于等于孩子i 的rate咋整?这个时候就不大好办了,因为我们不知道当前最好的选择是给孩子i+1多少糖果。
代码如下:
import java.util.Arrays;
/* * 典型的贪心算法 * 题本身可以用贪心法来做,我们用candy[n]表示每个孩子的糖果数,遍历过程中, * 如果孩子i+1的rate大于孩子i 的rate,那么当前最好的选择自然是:给孩子i+1的糖果数=给孩子i的糖果数+1 * 如果孩子i+1的rate小于等于孩子i 的rate咋整?这个时候就不大好办了, * 因为我们不知道当前最好的选择是给孩子i+1多少糖果。 * 解决方法是:暂时不处理这种情况。等数组遍历完了,我们再一次从尾到头遍历数组, * 这回逆过来贪心,就可以处理之前略过的孩子。 * 最后累加candy[n]即得到最小糖果数。 * */
public class Solution
{
public int candy(int[] ratings)
{
if(ratings==null || ratings.length<=0)
return 0;
int []num = new int[ratings.length];
Arrays.fill(num, 1);
for(int i=1;i<ratings.length;i++)
{
if(ratings[i]>ratings[i-1])
num[i]=num[i-1]+1;
}
for(int i=ratings.length-2;i>=0;i--)
{
if(ratings[i]>ratings[i+1] && num[i] < num[i+1]+1)
num[i]=num[i+1]+1;
}
int sum=0;
for(int i=0;i<num.length;i++)
sum+=num[i];
return sum;
}
}
下面是C++的做法,这道题是的典型的贪心算法的一个简单应用,需要好好学习
注意反向遍历的时候注意dp的比较
代码如下:
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
using namespace std;
class Solution
{
public:
int candy(vector<int>& r)
{
int n = r.size();
vector<int> dp(n, 1);
for (int i = 1; i < n; i++)
{
if (r[i] > r[i - 1])
dp[i] = dp[i - 1] + 1;
}
for (int i = n - 2; i >= 0; i--)
{
if (r[i] > r[i + 1] && dp[i] < dp[i + 1]+1)
dp[i] = dp[i + 1] + 1;
}
return accumulate(dp.begin(), dp.end(), 0);
}
};