从零开始---贪心算法

学习目标:贪心算法

掌握贪心算法,

学习内容:

提示:以后要学的内容
例如:
1、 贪心算法
2、 分而治之算法(递归)
3、 动态规划
4、 暴力解法



内容:

假设一个问题比较复杂,暂时找不到全局最优解,那么我们可以考虑把原问题拆分成几个小问题,分别求每个小问题的最优解,再叠加这些"全局最优解",就"当作"整个问题的最优解了

贪心算法3步走

第一步

明确到底什么是最优解,明确后记录下来

第二步

明确什么是子问题的最优解?再记录再本子上

第三步

分别求出子问题的最优解再堆叠出全局最优解

问题示意

背包问题

有一个背包,最大承受150公斤,现有7个物品,

重量价值
3510
3040
6030
5050
4035
1040
2530

要求怎么使背包背走最多价值的物品?

分析

对于选择的物品有一个总和限制,比如此时的重量,又希望另一个属性综合最大
此时按照我们的算法3步走

  1. 明确最优解
    在重量限制范围内,价值最大的选择,这就是最优解
  2. 明确子问题的最优解
    认为每次选择的当前价值最高的物品,这就是局部最优解
  3. 分别求出子问题的最优解在堆叠出全局最优解
    此时,我们按照每次选择最大的价值的商品,
    价值为:50->40->40->35=165
    对应的重量为 50+30+10+40=130
//  int[][] nums={{35,10},{30,40},{60,30}
//             ,{50,50},{40,35},{10,40},{25,30}};
 public  int[] d( int[][] nums){
        //背包最大能装150,int[1][0]为重量 int[1][1]为价值,求价值最大
        //我们按照每次选择最大的价值的商品
        int[] temp=new int[1];//临时变量
        for(int i=0; i<nums.length-1; i++){   //表示趟数,一共arr.length-1次。
            for(int j=nums.length-1; j>i; j--){
                if(nums[j][1] < nums[j-1][1]){
                    temp = nums[j];
                    nums[j] = nums[j-1];
                    nums[j-1]= temp;
                }
            }}
            //冒泡排序好了,按照价值以小到大
            int z=0;
            int perice=0;
        for (int i=nums.length-1;i>0;i-- ) {
            int[] dw=nums[i];
            if (z+dw[0]<=150){
                z+=dw[0];  perice+=dw[1];
            }else {
                break;
            }
        } 
            int[] maxPerice={z,perice};
            return  maxPerice;
    }

上面使用价值属性策略,如果我们换成重量来选择,每次选择最小的那个,则为:
重量为: 10+25+30+35+40=140,
价值为: 40+30+40+10+35=155

 public int[]  d1(int[][] nums){
 int[] temp=new int[1];//临时变量
        for(int i=0; i<nums.length-1; i++){   //表示趟数,一共arr.length-1次。
            for(int j=nums.length-1; j>i; j--){
                if(nums[j][0] > nums[j-1][0]){
                    temp = nums[j];
                    nums[j] = nums[j-1];
                    nums[j-1]= temp;
                }
            }}
        //排序好了
        int z=0;
        int perice=0;
        for (int i=nums.length-1;i>0;i-- ) {
            int[] dw=nums[i];
            if (z+dw[0]<=150){
                z+=dw[0];  perice+=dw[1];
            }else {
                break;
            }
        }
        int[] maxPerice={z,perice};
        return  maxPerice;
        }
        /**可以优化算法,去除排序,每次取出最小值的重量.
        *使用循环计算是否大于150,使用两个变量记录,每次查询的最小值重量和位置,循环查询最小值比之前的值要小,而后计算是否超过了最大值150,超过则退出
**/

这次换成价值密度来计算,没单位重量的价值,使用价值密度来分析,即价值除以重量

重量价值 -> 价值密度
3510 -> 0.28
3040 -> 1.3
6030 -> 0.5
5050 -> 1
4035 -> 0.875
1040 -> 4
2530 -> 1.2

每次都选价值密度最大的:
重量为:10+30+25+50+35=150 每次去除的范围内选择最大的
而价值为:40+40+30+50+10=170
此时我们问题的求解答案为最高

计算出相关的价值密度即可

我们是否能使用每次子问题都使用单位密度去定义呢?
其实不行,特定的方式只适合特定条件最优解

贪心算法的核心问题

使用贪心算法的前提

  1. 原问题复杂度过高
  2. 求全局最优解的数学模型难以建立
  3. 求全局最优解的计算量过大
  4. 没有太大必要一定要求出全局最优解,"比较优"就行

把原问题分解成子问题

  1. 按串行任务分
    时间串行的任务,按子任务来分解,即每一步都是在前一步的基础上再选择当前的最优解.
  2. 按规模递减分
    规模较大的复杂问题,可以借助递归思想,分解成一个小一点点的问题,循环解决,当最后一步的求解完成后就得到了所谓的"全局最优解"
  3. 按并行任务分
    该类问题不分先后,可能并行的,可以分别求解,再按照一定规则将其组合后得到最终解.

例题

leetCode: 443 55 435 376

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
从零开始学习贪心算法需要掌握以下几个点: 1. 贪心算法的定义:贪心算法是指在问题求解过程中,总是做出当前看来最好的选择,而不考虑整体最优解。贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。 2. 贪心算法的解题步骤:建立数学模型描述问题,将问题分解为若干个子问题,对每个子问题求解得到局部最优解,将局部最优解合成原问题的最优解。 3. 贪心算法与动态规划的关系:贪心算法是动态规划的一种特例。贪心算法不需要知道一个节点所有子树的情况,只需要选择当前问题的最优解路径,一直走到底即可。而动态规划需要自底向上构造子问题的解。 4. 活动选择问题是贪心算法的一个经典例子。在活动选择问题中,需要在同一天使用同一个教室举行多个活动,要求选择尽可能多的活动不冲突地进行。 综上所述,从零开始学习贪心算法,要理解贪心算法的定义和特点,掌握贪心算法的解题步骤,了解贪心算法与动态规划的关系,并通过经典例子如活动选择问题来实践和加深对贪心算法的理解。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [从0开始学贪心算法](https://blog.csdn.net/weixin_45024585/article/details/107515191)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [leetcode338-leetcode:从零开始](https://download.csdn.net/download/weixin_38750644/19950444)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [从零开始贪心算法](https://blog.csdn.net/qq_32400847/article/details/51336300)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值