一、贪心算法的基本思想

  在求解过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解。

  从贪心算法的定义可以看出,贪心算法不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一。

二、贪心算法的基本要素

  (1)最优子结构性质

  (2)贪心选择性质(局部最优选择)

三、贪心算法实例

  1、活动安排

  设有n个活动的集合 E = {1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。

  每个活动 i 都有一个要求使用该资源的起始时间 si 和一个结束时间 fi,且 si < fi。如果选择了活动i,则它在半开时间区间 [si ,fi ) 内占用资源。若区间 [si , fi )与区间 [sj, fj ) 不相交,则称活动i与活动j是相容的。当 si ≥ fj 或 sj ≥ fi 时,活动 i 与活动 j 相容。

  活动安排问题就是在所给的活动集合中选出最大的相容活动子集合。

  例如:

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. #define NUM 50
  5.  
  6. void GreedySelector(int n, int s[], int f[], bool b[])
  7. {
  8. b[]=true; //默认将第一个活动先安排
  9. int j=; //记录最近一次加入b中的活动
  10.  
  11. //依次检查活动i是否与当前已选择的活动相容
  12. for(int i=;i<=n;i++)
  13. {
  14. if (s[i]>=f[j])
  15. {
  16. b[i]=true;
  17. j=i;
  18. }
  19. else
  20. b[i]=false;
  21. }
  22. }
  23.  
  24. int main()
  25. {
  26. int s[] = {,,,,,,,,,,,}; //存储活动开始时间
  27. int f[] = {,,,,,,,,,,,}; //存储活动结束时间
  28. bool b[NUM]; //存储被安排的活动编号
  29. int n = (sizeof(s) / sizeof(s[])) - ;
  30.  
  31. GreedySelector(n, s, f, b);
  32.  
  33. for(int i = ; i <= n; i++) //输出被安排的活动编号和它的开始时间和结束时间
  34. {
  35. if(b[i]) cout << "活动 " << i << " :" << "(" << s[i] << "," << f[i] << ")" <<endl;
  36. }
  37. return ;
  38. }

  2、背包问题

  给定一个载重量为 M 的背包,考虑 n 个物品,其中第 i 个物品的重量 wi(1 ≤ i ≤ n),价值 vi(1 ≤ i ≤ n),要求把物品装满背包,且使背包内的物品价值最大。
  有两类背包问题(根据物品是否可以分割),如果物品不可以分割,称为 0—1 背包问题(动态规划);如果物品可以分割,则称为背包问题(贪心算法)。

  例如:

  有3种方法来选取物品:

    (1)当作 0—1 背包问题,用动态规划算法,获得最优值 220;
    (2)当作 0—1 背包问题,用贪心算法,按性价比从高到底顺序选取物品,获得最优值 160。由于物品不可分割,剩下的空间白白浪费。
    (3)当作背包问题,用贪心算法,按性价比从高到底的顺序选取物品,获得最优值 240。由于物品可以分割,剩下的空间装入物品 3 的一部分,而获得了更好的性能。

图2.1 背包问题

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. #define NUM 50
  5.  
  6. //这里假设 w[], v[] 已按要求排好序
  7. void Knapsack(int n,float M,float v[],float w[],float x[])
  8. {
  9. int i;
  10. for(i = ; i <= n; i++) x[i] = ; //初始化数组
  11. float c = M;
  12. for(i = ;i <= n; i++) //全部被装下的物品,且将 x[i] = 1
  13. {
  14. if(w[i]>c) break;
  15. x[i] = ;
  16. c -= w[i];
  17. }
  18.  
  19. if(i <= n) x[i] = c / w[i]; //将物品i 的部分装下
  20. }
  21.  
  22. int main()
  23. {
  24. float M = ; //背包所能容纳的重量
  25. float w[] = {,,,}; //这里给定的物品按价值降序排序
  26. float v[] = {,,,};
  27. float x[NUM]; //存储每个物品装入背包的比例
  28.  
  29. int n = (sizeof(w) / sizeof(w[])) - ;
  30.  
  31. Knapsack(n, M, v, w, x);
  32.  
  33. for(int i = ; i <= n; i++)
  34. cout << "物品 " << i << " 装入的比例: " << x[i] << endl;
  35. return ;
  36. }

[C++] 贪心算法之活动安排、背包问题的更多相关文章

  1. 贪心算法求解活动安排<算法分析>

    一.实验内容及要求 1.要求按贪心算法原理求解问题: 2.要求手工输入s[10]及f[10],其中注意自己判断s[i]<f[i]: 3.要求显示所有活动及最优活动安排的i事件列表.二.实验步骤  ...

  2. C++贪心算法实现活动安排问题

    问题描述: 设有n个活动的集合E={1,2,…,n},其中,每个活动都要求使用同一资源,而在同一时间内只有一个活动能使用这一资源.每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且s ...

  3. 51nod贪心算法入门-----活动安排问题

    有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 输入 第1行:1个数N,线段的数量(2 <= N <= 10000) 第2 ...

  4. 51nod贪心算法入门-----活动安排问题2

    题目大意就是给几个活动,问要几个教室能够弄完. 这个题目的想法就是把活动的开始——结束的时间看做是数轴上的一段线段,教室的个数就是在某点的时间厚度,求最大的时间厚度就是所需要的教室个数. #inclu ...

  5. 雷达覆盖,贪心,类似活动安排(POJ1328)

    题目链接:http://poj.org/problem?id=1328 解题报告: 1.按照头结点排序. #include <cstdio> #include <cmath> ...

  6. js算法初窥05(算法模式02-动态规划与贪心算法)

    在前面的文章中(js算法初窥02(排序算法02-归并.快速以及堆排)我们学习了如何用分治法来实现归并排序,那么动态规划跟分治法有点类似,但是分治法是把问题分解成互相独立的子问题,最后组合它们的结果,而 ...

  7. 忙碌的Nova君 (活动安排问题、贪心算法)

    题目描述 理论上,Nova君是个大闲人,但每天还是有一大堆事要干,大作业啦,创新杯啦,游戏啦,出题坑人啦,balabala......然而精力有限,Nova君同一时间只能做一件事,并不能一心二用.假设 ...

  8. hdu 2037简单贪心--活动安排问题

    活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子.该问题要求高效地安排一系列争用某一公共资源的活动.贪心算法提供了一个简单.漂亮的方法使得尽可能多的活动 ...

  9. 贪心算法_01背包问题_Java实现

    原文地址:http://blog.csdn.net/ljmingcom304/article/details/50310789 本文出自:[梁敬明的博客] 1.贪心算法 什么是贪心算法?是指在对问题进 ...

随机推荐

  1. 单文件夹下的C程序如何编写Makefile文件

    通过学习已经学会了GCC的一些基础的命令,以及如何将C语言源代码编译成可执行文件. 我们已经知道在linux环境下编译源码时,常会有以下三个步骤: ./configure make make clea ...

  2. JMeter学习(十一)属性和变量

    一.Jmeter中的属性: 1.JMeter属性统一定义在jmeter.properties文件中,我们可以在该文件中添加自定义的属性 2.JMeter属性在测试脚本的任何地方都是可见的(全局),通常 ...

  3. Centos6.5安装Mysql5.6.10

    1. 先卸载掉老版本的mysql(linux严格区分大小写,查找的时候加上-i参数,和mysql相关的全部要卸) [root@liuchao ~]# rpm -qa | grep -i mysqlMy ...

  4. 用java.lang.Math.random()语句,随机输出{size:自定义参数}个数不重复并且按顺序从小到大排列(冒泡排序)

    package com.test; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lan ...

  5. 文件系统中跳转【TLCL】

    pwd - Print name of current working directory cd - Change directory ls - List directory contents Lin ...

  6. bzoj 1101 zap 莫比乌斯

    1101: [POI2007]Zap Time Limit: 10 Sec  Memory Limit: 162 MB Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给 ...

  7. Lightoj 1370 素数打表 +二分

    1370 - Bi-shoe and Phi-shoe   PDF (English) Statistics   Time Limit: 2 second(s) Memory Limit: 32 MB ...

  8. Oracle创建表空间和增加表空间

    1.创建表空间 create tablespace fgq datafile 'E:\app\Administrator\oradata\fms\fgq01.dbf' size 1000M autoe ...

  9. Python快速学习-函数

    函数定义总结: 1.定义函数时,需要确定函数名和参数个数:2.如果有必要,先对参数的数据类型进行检查:3.函数体内部可以用return随时返回函数结果:4.函数执行完毕没有return语句时,自动re ...

  10. mysql: 模糊查询 feild like keyword or feild like keyword , concat(feild1,feild2,feild3) like keyword

    mysql: 模糊查询 feild like '%keyword%' or feild like'% keyword%' , 或者 concat(feild1,feild2,feild3) like ...