经典算法之贪心(Greedy)

1、贪心的定义

  贪心算法是什么意思?举个例子就很清楚了:现在你有一个能装4斤苹果的袋子,苹果有两种,一种3斤一个,一种2斤一个,怎么装才能得到最多苹果?当然我们人考虑的话当然是拿两个2斤的苹果,就刚好装满了,但是如果按贪心算法拿的话,首先就要把最重的苹果拿下(是不是很符合贪心两个字?),但并没有得到最多苹果。

  贪心算法在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

2、贪心的思想

1. 建立数学模型来描述问题;

2. 把求解的问题分成若干个子问题;

3. .对每一子问题求解,得到子问题的局部最优解;

4. 把子问题的解局部最优解合成原来解问题的一个解。

3、贪心的要素

(1)贪心选择

  什么叫贪心选择?从字义上就是贪心也就是目光短线。贪图眼前利益。在算法中就是仅仅依据当前已有的信息就做出选择,并且以后都不会改变这次选择。(这是和动态规划法的主要差别)。

  所以对于一个详细问题。要确定它是否具有贪心选择性质,必须证明每做一步贪心选择是否终于导致问题的总体最优解。
  
(2)最优子结构

  当一个问题的最优解包括其子问题的最优解时,称此问题具有最优子结构性质。

  这个性质和动态规划法的一样,最优子结构性质是可用动态规划算法或贪心算法求解的关键特征。

4、贪心算法的典型应用

  背包问题(物体可切分时的0-1背包问题),Huffman编码,单源最短路径,Prim算法,Kruskal算法等都是贪心算法的经典应用。

  下面是HackerRank中买房问题的demo:

/*
Lauren has a chart of distinct projected prices for a house over the next n years, 
where the price of the house in the  year is i. 
She wants to purchase and resell the house at a minimal loss according to the following rules:

The house cannot be sold at a price greater than or equal to the price it was purchased at 
(i.e., it must be resold at a loss).
The house cannot be resold within the same year it was purchased.

Find and print the minimum amount of money Lauren must lose if she buys the house and resells 
it within the next  years.

Note: It's guaranteed that a valid answer exists.

Sample Input 1
5
20 7 8 2 5

Sample Output 1
2

buys the house in year 2, sells it in year 5(7-5=2).
*/

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int main(int argc, char const *argv[])
{
    using llt = long long int;
    int n;
    cin >> n;
    vector> vec;
    for (llt i = 0; i < n; ++i)
    {
        llt j;
        cin >> j;
        vec.push_back(make_pair(j, i));
    }
    llt y = 100000000;
    //把房价排序
    sort(vec.rbegin(), vec.rend());
    for (llt i = 0; i < n - 1; ++i)
    {
        if (vec[i].first - vec[i + 1].first < y && vec[i].second < vec[i + 1].second)
            y = vec[i].first - vec[i + 1].first;
    }
    cout << y;
    return 0;
}

你可能感兴趣的:(贪心算法,经典算法及分析)