Greedy algorithm works only if the local optimum is equal to the global optimum.

活动选择问题

Consider any nonempty subproblem SkS_kSk​, and let am be an activity in SkS_kSk​ with the earliest finish time. Then am is included in some maximum-size subset of mutually compatible activities of SkS_kSk​

背包问题

动态规划算法

f[i][v]:表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。

状态转移方程是:f[i][v]=max{f[i-1][v],f[i-1][v-weight[i]]+value[i]}

“将前i件物品放入容量为v的背包中”这个子问题,如果只考虑第i件物品放或者不放,那么就可以转化为只涉及前i-1件物品的问题:

  1. 如果不放第i件物品,则问题转化为“前i-1件物品放入容量为v的背包中”;

  2. 如果放第i件物品,则问题转化为“前i-1件物品放入剩下的容量为v-weight[i]的背包中”,此时能获得的最大价值就是f [i-1][v-weight[i]],再加上通过放入第i件物品获得的价值value[i]。

f[i][v]的值就是1、2中最大的那个值。

// 背包问题
#include <iostream>
#include <algorithm>
using namespace std;  #define N 3 // N件宝贝
#define C 5 // C是背包的总capacity    int main()
{  int value[N + 1] = { 0, 60, 100, 120 }; // 价值    int weight[N + 1] = { 0, 1, 2, 3 };     // 重量    int f[N + 1][C + 1] = { 0 };   // f[i][j]表示在背包容量为j的情况下,前i件宝贝的最大价值    int i = 1;  int j = 1;  for (i = 1; i <= N; i++)        //外循环控制物品数量,确保每个物品都会被遍历到  {  /*for (j = weight[i]; j <= C; j++)      //内循环控制物品的重量,确保能够遍历出“以前每个物品放入时的最大价值f[i][j]” { int x = f[i - 1][j];        //不放第i件物品 int y = f[i - 1][j - weight[i]] + value[i];      //放入第i件物品 f[i][j] = max(x, y); }*/  for (j = 1; j <= C; j++)  {  // 递推关系式    if (j < weight[i])  {  f[i][j] = f[i - 1][j];  }  else  {  int x = f[i - 1][j];  int y = f[i - 1][j - weight[i]] + value[i];  f[i][j] = max(x, y);  }  }  }  for (i = 0; i <= N; i++)  {  for (j = 0; j <= C; j++)  {  printf("%4d ", f[i][j]);  }  cout << endl;  }  cout << endl << "选取的最大价值是:" << f[N][C] << endl;  cout << "选取的物品如下:" << endl;  i = N, j = C;  while (i)  {  if (f[i][j] == (f[i - 1][j - weight[i]] + value[i]))  {  cout << i << ":" << "weight=" << weight[i] << ", value=" << value[i] << endl;  j -= weight[i];  }  i--;  }  cout << endl;  return 0;
}

优化空间复杂度:

上面f[i][v]使用二维数组存储的,可以优化为一维数组f[v],将主循环改为:

for i = 1…N;

for v = V…0;

f[v] = max(f[v], f[v-c[i]]+w[i]);

即将第二层循环改为从V…0,逆序。

#include <iostream>
#include <vector>
using namespace std;  const int MIN = 0x80000000;
const int N = 3;   //物品数量
const int V = 5;  //背包容量
int f[V + 1];              // 一维数组  int Package(int *W, int *C, int N, int V)
{  int i, j;  memset(f, 0, sizeof(f));  //初始化为0  for (i = 1; i <= V; i++)       //此步骤是解决是否恰好满足背包容量,  f[i] = MIN;                // 若“恰好”满足背包容量,即正好装满背包,则加上此步骤; 若不需要“恰好”,则初始化为0  for (i = 1; i <= N; i++)  for (j = V; j >= C[i]; j--)    //注意此处与解法一是顺序不同的,弄清原因  {  f[j] = (f[j]>f[j - C[i]] + W[i]) ? f[j] : (f[j - C[i]] + W[i]);  cout << "f[" << i << "][" << j << "]=" << f[j] << endl;  }  return f[V];
}  void main()
{  int W[4] = { 0, 7, 5, 8 };      //物品权重  int C[4] = { 0, 2, 3, 4 };      //物品大小  int result = Package(W, C, N, V);  if (result > 0)  {  cout << endl;  cout << "the opt value:" << result << endl;  }  else  cout << "can not find the opt value" << endl;    // 可能不存在正好装满背包的解
}

在求最优解的背包问题中,一般有两种不同的问法:

1.要求“恰好装满背包”时的最优解:
在初始化时除了 f[0] 为 0其它f[1…V]均设为 -∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。如果不能恰好满足背包容量,即不能得到 f[V] 的最优值,则此时 f[V] =-∞,这样就能表示没有找到恰好满足背包容量的最优值。

2.求小于等于背包容量的最优解,即不一定恰好装满背包:
如果并没有要求必须把背包装满,而是只希望价值尽量大,初始化时应该将f[0…V]全部设为0。

Exercise

https://blog.csdn.net/zwpf1994/article/details/79083972

Greedy Algorithm相关推荐

  1. 数据结构与算法(C++)– 贪婪算法(Greedy algorithm)

    贪婪算法(Greedy algorithm) 1.基础 定义:贪婪算法分阶段地工作,在每一阶段,选择在当前最好的决策,不考虑将来的后果.所以一般只能得到局部最优而不是全局最优. 贪婪算法: Dijks ...

  2. 动态规划(Dynamic Programming)与贪心算法(Greedy Algorithm)

    文章目录 动态规划算法(Dynamic Programming) 动态规划问题的属性 应用实例:最长公共子序列问题(Longest Common Subsequence, LCS) 贪心算法(Gree ...

  3. 贪心(Greedy Algorithm)

    贪心(Greedy Algorithm) 贪心 44.通配符匹配 45.跳跃游戏 II 55.跳跃游戏 122.买卖股票的最佳时机II 134.加油站 135.分发糖果 179.最大数 277.搜寻名 ...

  4. 贪婪算法-Greedy algorithm

    贪婪算法(greedy algorithm) WIKI A greedy algorithm is an algorithmic paradigm that follows the problem s ...

  5. 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal#39;s algorithm)

    克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...

  6. Arithmetic_Thinking -- greedy algorithm

    贪心算法--就是一种寻找局部最优解的情况,然后整合成整体最优解的情况 简单的例子:买菜的找钱,现在有1元,5角,1角的硬币,要找给别人2元7角,现在是怎么才能以最少的硬币量找给别人,肯定是先来两个1元 ...

  7. 贪心算法(Greedy Algorithm)之霍夫曼编码

    文章目录 1. 贪心算法 2. 应用 2.1 找零钱 2.2 区间覆盖 2.3 霍夫曼编码 霍夫曼编码完整代码 1. 贪心算法 我们希望在一定的限制条件下,获得一个最优解 每次都在当前的标准下做出当下 ...

  8. 贪婪算法(greedy Algorithm)

    贪婪算法的应用: 相关算法练习题: LeetCode股票买卖的最佳时机 LeetCode判断子序列 LeetCode 分发饼干 LeetCode跳跃游戏 LeetCode加油站 一.简单调度问题: 给 ...

  9. 实验12 Greedy Algorithm练习题 答案与解析

    1-1 只有当局部最优跟全局最优解一致的时候,贪心法才能给出正确的解.(1分) T 1-2 Let S be the set of activities in Activity Selection P ...

  10. 【控制】贪心算法(GA,Greedy Algorithm)及 Matlab 实现

    文章目录 算法思路 应用实例 仿真 Ref. 算法思路 贪心算法一般按如下步骤进行: 建立数学模型来描述问题. 把求解的问题分成若干个子问题. 对每个子问题求解,得到子问题的局部最优解. 把子问题的解 ...

最新文章

  1. 上周回顾:微软与苹果比赛谁更“不安全”
  2. 30分钟学会mysql_30分钟回顾MySQL语法(下)
  3. boost::math模块计算 Bessel 和 Neumann 函数的零点的测试程序
  4. idea如何设置自动换行
  5. 昨天登陆页面,无法进入后台,今天攻克了
  6. Quartz使用总结、Cron表达式
  7. LeetCode 277. 搜寻名人(思维题)
  8. 计算机应用技术自创ppt,教师必备:超好用的课件制作工具
  9. linux screen vim 颜色不一样,tmux中的Vim显示错误的颜色
  10. HTML+CSS制作七夕跳动的红心动画效果
  11. 一、华为设备telnet命令配置
  12. Matplotlib 全部笔记的思维导图精简记忆版
  13. java nginx报502,Nginx 502错误排查及解决办法
  14. 树和二叉树的基本概念及性质
  15. 与技术无关,但却值得码农们好好读一读的怪书:禅与摩托车维修艺术
  16. 怎么批量提取多个 Excel 文档中的图片
  17. APP项目软件开发流程
  18. 货代公司主要是做什么的呢|货代公司作用
  19. 电路板排针拆除(拔出)方法
  20. 看看成功例子 四款iPhone音乐APP应用赏析

热门文章

  1. Win10 中主机名hosts 文件位置
  2. 计算机办公软件应用中级,计算机办公软件应用中级和计算机123级有什 – 手机爱问...
  3. AJAX聊天室实现原理 JQuery+PHP 【转】
  4. 第五节:蜂鸣器的驱动程序
  5. dof景深matlab,Shader学习(三):DOF(景深)
  6. 已知线段上某点与起点的距离,求该点的坐标
  7. SOLIDWORKS如何自动生成图纸
  8. 树莓派CM4六路串口设置及使用
  9. Android 9 (P)在user模式下无法使用fastboot烧录怎么破
  10. (翻译)锚定效应(Anchoring)