首页 > 编程语言 >算法进阶

算法进阶

时间:2023-11-05 17:45:30浏览次数:40  
标签:背包 进阶 money li 算法 拿走 贪心

贪心算法

定义

是指在对问题求解时,总是做出当前看来是最好的选择,着眼于眼前(做出目前对自己好的:贪心),不从整体最优上考虑,做出某种意义上的局部最优解。但有时贪心算法的解就是最优解。要会判断一个问题是否用贪心算法来计算。

例题

  1. 找零问题:假设商店老板需要找零n元钱,钱币的面额有:100元、50元、20元、5元、1元,如何找零使得所需钱币的数量最少?
  2. 代码求解
li = [i for i in map(int,input().split())]
money = int(input())
def pay_money(li,money):
    m = [0 for _ in range(len(li))]
    li = sorted(li,reverse=True)
    for index,val in enumerate(li):
        m[index] = money//val
        money = money % val
    return m,money
print(pay_money(li,money))

背包问题

0-1背包

有时需要判断0-1背包是否能用贪心算法来做:有时局部的最优解没能装满背包,且导致不是整体最优解

分数背包

对于分数背包而言,使用贪心算法来做一定是整体最优解:背包一定是满的,一点都不剩

举例

一个小偷在某个商店发现有n个商品,第i个商品价值vi元,重wi千克。他希望拿走的价值尽量高,但他的背包最多只能容纳W千克的东西。他应该拿走哪些商品?

image

  • 贪心算法:找到当前的最优解:每个单位商品的价值:商品1、2、3的价值分别为6,5,4

  • 0-1背包对于一个商品,小偷要么把它完整拿走,要么留下。不能只拿走一部分,或把一个商品拿走多次。(商品为金条)

    因此,若用贪心算法求解,0-1背包只能拿贪心算法中价值最大的前两个,即商品1和商品2,共计160元,30千克,背包容量为50,50-30<30,不能再拿商品3。而不使用贪心算法,拿商品2和商品3,共计220元,50千克,该决策优于贪心算法决策。

  • 分数背包对于一个商品,小偷可以拿走其中任意一部分。(商品为金沙)

    无论是否使用贪心算法,都能使得决策为最优解(该例子分数背包在使用贪心算法下,可拿10千克商品1,20千克商品2和20千克商品3,共计240元)

    # 分数背包问题贪心算法求解
    goods = [(60,10),(100,20),(120,30)]     # 每个商品对应的价值即重量
    W = 50                                  # 背包容量
    goods.sort(key=lambda x: x[0] / x[1], reverse=True)     # 贪心算法思想(对当前每个商品的价值进行排序,从大到小排序)
    def fractional_package(goods,W):
        m = [0 for _ in range(len(goods))]          # 用于存放对应每个商品(从大价值到小价值)拿走的数量
        total_price = 0                 # 用于存放拿走的价值总数
        for index,(price, weight) in enumerate(goods):
            if W >= weight:             # 如果当前背包容量大于或等于大价值的重量时,可都拿走
                m[index] = 1            # 1代表都拿走
                total_price += price
                W -= weight             # 背包总量要改变
            else:                       # 当前背包容量小于大价值的重量时,拿走部分
                m[index] = W/weight     # 表示拿走商品总重量的几分之几
                total_price += m[index] * price
                W = 0                   # 当前无背包空间
                break
        return total_price,m
    print(fractional_package(goods,W))
    

拼接最大数字问题

  1. 题目

image

  1. 思想:比首位,首位大的先排,当首位一样,比下一位,以此类推,当都一样只是长度不同,则两数相加进行比较,如何大的数进行存放(两数已排好序)

  2. 代码实现***(待搞懂cmp_to_key用法)

li = [32,94,128,1286,6,71]
from functools import cmp_to_key
def num_cmp(x,y):           # 自定义排序规则
  if x + y > y + x:
      return 1
  elif x + y < y + x:
      return -1           # 当返回一个负数时,改变原本的排序顺序(由后往前进行比较,插入)
  else:
      return 0
def num_join(li):
  li = list(map(str,li))
  li.sort(key=cmp_to_key(num_cmp),reverse=True)
  return li
print("".join(num_join(li)))

活动选择问题

  1. 题目
    image

  2. 思想:贪心算法结论:最早结束的活动一定是最优解的一部分。最早结束的先举办。结束时间与开始时间不相撞

  3. 代码实现

activities = [(1,4),(3,5),(0,6),(5,7),(3,9),(5,9),(6,10),(8,11),(8,12),(2,14),(12,16)]
def activity_choose(li):
    li.sort(key=lambda x:x[1])      # 以结束时间为比较对象,按最先结束的先安排为原则进行活动安排
    activities_final_choose = [li[0]]   # 最先结束一定存在在活动的最先选择中
    for i in range(1,len(li)):
        if li[i][0] >= activities_final_choose[-1][1]:   # 判断活动开始时间是否大于已排好的最后一个活动的结束时间
            activities_final_choose.append(li[i])
    return activities_final_choose
print(activity_choose(activities))

贪心算法总结

需要get到该问题是贪心的,知道贪啥,按啥来贪

上述问题采用的贪心算法的共同点:

  • 都是最优化问题(最多/大,最少/小)

动态规划

标签:背包,进阶,money,li,算法,拿走,贪心
From: https://www.cnblogs.com/byyya/p/17810803.html

相关文章

  • 排序算法
    一、选择排序12,23,8,15,33,24,77,558,23,12,15,33,24,77,558,12,23,15,33,24,77,558,12,15,23,33,24,77,558,12,15,23,24,33,77,558,12,15,23,24,33,55,77二、冒泡排序12,23,8,15,33,24,77,5512,23,8,15,33,24,55,7712,23,8,15,24,33,55,7712,8,23,15,24,33,55,7712,8,15,23,......
  • 用欧几里得算法求两个数的最大公约数
    一.什么是欧几里得算法1.欧几里得算法就是辗转相除法,用于求两个数的最大公约数。如果用gcd(a,b)表示a和b的最大公约数,gcd(a,b)=gcd(b,a%b),当a%b==0时,b就是最大公约数。2.算法说明:首先按照大小输入两个整数a、b,再用一个中间量用来存放二者的余数。计算后将b的值赋给a,将余数赋给b......
  • 【教3妹学编程-算法题】使数组变美的最小增量运算数
    2哥 :3妹,脸上的豆豆好了没呢。3妹:好啦,现在已经没啦2哥 :跟你说很快就会消下去的,还不信~既然你的容颜和心情都如此美丽,那我们就再做一道关于美丽的题吧。3妹:切,2哥就会取笑我,伤心时让我做题,开心时也让我做题! 1题目: 给你一个下标从0开始、长度为n的整数数组nums,和一个整......
  • c++实现排序算法
    排序算法选择排序#include<iostream>#include<cmath>usingnamespacestd;intmain(){ intn,i,j,a[2000]; boolt; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<n;i++) for(j=i+1;j<=n;j++) if......
  • 【python进阶】14大模块200页知识体系md笔记,第4篇:linux命令进阶(2)
    本文从14大模块展示了python高级用的应用。分别有Linux命令,多任务编程、网络编程、Http协议和静态Web编程、html+css、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。完整版笔记直接地址:请移步这里共14......
  • Dijkstra, RIP, OSPF:RIP算法
    这部分参考王道bilibili视频:https://www.bilibili.com/video/BV19E411D78Q?p=56&vd_source=63764dd9776224d187bddddb05bf9f3f 例题-1:R6、R4相邻,如左图所示。现在R4的路由表更新为右上表,现在让你写出R6更新后的路由表。  例题-2:这道题中向量6个元素分别代表某个路......
  • m基于5G通信的超密集网络多连接负载均衡和资源分配算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:2.算法涉及理论知识概要5G模型的基本结构如下所示:超密集网络是5G通信系统中的重要技术,是现在通信界的研究热点。系统中的每个小小区都是正交频分多址系统,共有TV个小小区,每个小小区使用个OFDMA子载波,信道增益为G。根据其结构图可知,当......
  • m基于5G通信的超密集网络多连接负载均衡和资源分配算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要        5G模型的基本结构如下所示:          超密集网络是5G通信系统中的重要技术,是现在通信界的研究热点。系统中的每个小小区都是正交频分多址系统,共有TV个小小区,每个小......
  • JavaSE(09) - 面向对象进阶
    JavaSE(09)-面向对象进阶p121static关键字static表示静态,是java中的一个修饰符,可以修饰成员方法,成员变量.一,被static修饰的成员变量,叫做静态变量.特点:被改类所有对象共享不属于对象属于类随着类的加载而加载,优先于对象存在调用方式:类名调用(推荐)对......
  • JavaSE(10) - 面向对象进阶
    JavaSE(10)-面向对象进阶P129认识多态(polymorphism)多态就是对象的多种形态多态的前提是:1,有继承/实现关系2,有父类引用指向子类对象3,有方法重写多态的好处:使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利P130多态调用成员的特点调用......