“贪心算法(greedy algorithm,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。”
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。
买卖股票的最佳时机II
题见:卖卖股票的最佳时机II
我们可以发现,在这个问题中股票可以在当天买入,当天卖出,而且可以交易股票多次
局部最优:获取正利润
整体最优: 所有正利润的和
所以,假设每两天进行一次交易,如果利润为正值,就进行交易,否则不买入也不售出股票
int main()
{
int n;
cin >> n;
vector<int>price(n, 0);
for (int i = 0; i < n; i++)
{
cin >> price[i];
}
int maxs = 0;
for (int i = 0; i < n - 1; i++)
{
int count = price[i + 1] - price[i];
if (count > 0)
maxs += count;
}
cout << maxs << endl;
return 0;
}
分发糖果问题
题见:分发糖果
整个过程分为两部分:从前向后的遍历和从后向前的遍历
从前向后遍历,右边评分大于左边,ratings[i] 与 ratings[i - 1]比较
谁大谁获得更多的糖果,candyNum[i] 为第 i 个孩子应
该得到的糖果,此时的贪心策略为:
if(ratings[i]>ratings[i-1]) candy[i] = candy[i-1] + 1
else candy[i] = 1
从后向前遍历,左边评分大于右边,ratings[i] 与 ratings[i + 1]比较
还是大着获得更多的糖果,此时candyNum的贪心策略为
candyNum[i] = Math.max(candyNum[i+1]+1, candyNum[i]);
最后再遍历 candyNum[i],将每个孩子所需要的糖果数加和,就得到了最少糖果数目
int main()
{
int n;
cin >> n;
vector<int>ratings(n, 0);
vector<int>candy(n, 0);
for (int i = 0; i < n; i++)
{
cin >> ratings[i];
}
candy[0] = 1;
for (int i = 1; i < n; i++)//从前向后
{
if (ratings[i] > ratings[i - 1])
candy[i] = candy[i - 1] + 1;
else
candy[i] = 1;
}
for (int i = n - 2; i >= 0; i--)//从后向前
{
if (ratings[i] > ratings[i + 1])
candy[i] = max(candy[i], candy[i + 1] + 1);
}
int sum = accumulate(candy.begin(), candy.end(), 0);
cout << sum << endl;
return 0;
}