贪心问题详解

来源:互联网 发布:求解最短路径的算法 编辑:程序博客网 时间:2024/09/21 06:35

贪心算法思想:

顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

贪心算法的基本要素:

1.贪心选择性质。所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。

动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。

对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。

2. 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

贪心算法的基本思路:

从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。

该算法存在问题:

1. 不能保证求得的最后解是最佳的;

2. 不能用来求最大或最小解问题;

3. 只能求满足某些约束条件的可行解的范围。

实现该算法的过程:

从问题的某一初始解出发;

while 能朝给定总目标前进一步 do

   求出可行解的一个解元素;

由所有解元素组合成问题的一个可行解;

用背包问题讲解贪心:

01背包问题:有一个背包,背包容量是M=30。有3个物品,要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

我们制定贪心的策略总共有3种: 
1. 每次挑选重量最小的放入背包 
2. 每次挑选价值最大的放入背包 
3. 每次挑选单位重量价值最大的放入背包

我们试着来证明这三种可行: 
第一种: 
物品:A B C 
重量 10 30 10 
价值 20 80 20

每次挑选重量最小,AC放入背包后,B就不能放入背包了,放入AC的价值为40,而选择放入B的价值为80,明显不成立

第二种:和第一种类似

第三种: 
物品:A B C 
重量 10 30 10 
价值 10 30 10 
每次挑选单位重量价值最大,ABC的单位重量价值都一样,无法选择,因此也不成立。

总结: 
证明了,01背包问题是不能使用贪心算法来解决的,而是应该使用动态规划—— 动态规划 01背包问题

但是如果加一个条件,物品是可以拆分的,那么此背包问题就可以用贪心算法来解决,因此可以拆分,使得背包空间得到充分利用

可拆分物品背包问题代码实现

#include<iostream>#include<algorithm>using namespace std;const int MAXN = 100;//事先按照单位重量的商品价值排序了 float weight[MAXN] = {10,30,20,5};//商品重量 float value[MAXN] = {200,400,100,10}; //商品价值 float x[MAXN];//保存能存放物品的比例 int N = 4;float M;void bag(){    int i = 0;    for(i; i < N; i++){        if(weight[i] > M){            break;        }        x[i] = 1;        M -= weight[i];    }    if(i < N){        x[i] = M / weight[i];    }}int main(){    cin >> M;    bag();    for(int i = 0; i < N; i++){        cout << "背包能放入物品" << i+1 << "的比例:" << x[i] << endl;     }} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里,我使用的是第三种策略。


原创粉丝点击