【算法进阶1】贪心算法、背包问题(0-1背包、分数背包)、拼接最大数字问题、活动选择问题

news2024/9/21 2:33:32

1 贪心算法
2 背包问题
2.1 0-1背包问题
2.2 分数背包
3 拼接最大数字问题
4 活动选择问题

1 贪心算法

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

贪心算法并不保证会得到最优解,但是在某些问题上贪心算法的解就是最优解。
要会判断一个问题能否用贪心算法来计算。

在这里插入图片描述

from typing import List, Tuple


def change(t: List[int], n: int) -> Tuple[List[int], int]:
    """
    根据可用面额的列表 `t`,计算将金额 `n` 换成不同面额的硬币或纸币的最少数量。

    :param t: 可用面额的列表(整数列表),假设已给定的面额都是正数
    :param n: 需要兑换的金额(整数)
    :return: 一个元组,包含两个元素:
             - 一个列表,其中每个元素表示使用相应面额的数量
             - 剩余未兑换的金额(整数)
    """
    t.sort(reverse=True)  # 按面额从大到小排序,以便优先使用较大面额的货币
    m = [0 for _ in range(len(t))]  # 初始化结果列表 `m`,存储每种面额的使用数量

    # 遍历每一种面额
    for i, money in enumerate(t):
        m[i] = n // money  # 计算当前面额最多可以使用多少次
        n = n % money  # 计算剩余未兑换的金额

    return m, n  # 返回使用的面额数量列表和剩余未兑换的金额


t = [100, 50, 20, 5, 1]
print(change(t, 376))  # ([3, 1, 1, 1, 1], 0)
print(t)  # [100, 50, 20, 5, 1]

2 背包问题

在这里插入图片描述
在这里插入图片描述

2.1 0-1背包问题

def knapsack(weights: List[int], values: List[int], W: int) -> int:
    """
    0-1 背包问题的解决方案。
    
    :param weights: 每个金条的重量列表
    :param values: 每个金条的价值列表
    :param W: 背包的最大容量
    :return: 背包中可以放入的最大价值
    """
    n = len(weights)
    
    # 初始化 DP 表,行数为金条的数量+1,列数为背包的容量+1
    dp = [[0] * (W + 1) for _ in range(n + 1)]
    
    # 填充 DP 表
    for i in range(1, n + 1):
        for w in range(1, W + 1):
            if weights[i-1] <= w:  # 如果当前金条的重量小于等于当前容量
                # 选择放或不放当前金条,取最大值
                dp[i][w] = max(dp[i-1][w], dp[i-1][w-weights[i-1]] + values[i-1])
            else:
                # 不能放当前金条,只能继承前一个状态的值
                dp[i][w] = dp[i-1][w]
    
    return dp[n][W]  # 返回背包的最大价值

# 示例
weights = [2, 3, 4, 5]  # 每个金条的重量
values = [3, 4, 5, 6]   # 每个金条的价值
W = 8  # 背包的容量

# 计算最大价值
max_value = knapsack(weights, values, W)
print(max_value)  # 输出 10

2.2分数背包

from typing import List, Tuple


def fractional_backpack(goods: List[Tuple[int, int]], w: int) -> Tuple[float, List[float]]:
    """
    分数背包问题的解决方案(贪心算法)。

    这个算法用于在给定背包容量的情况下,最大化所能获得的总价值,并允许将物品分割成任意比例。

    :param goods: 一个包含物品的列表,每个物品用一个元组表示,其中第一个值是物品的价值,第二个值是物品的重量
    :param w: 背包的容量(整数)
    :return: 一个元组,其中第一个元素是总价值(浮点数),第二个元素是一个列表,表示每种物品被选择的比例
    """
    # 初始化列表 `m` 用于记录每种物品被选择的比例,初始时所有比例为 0
    m = [0.0 for _ in range(len(goods))]

    total_price = 0.0  # 用于累加总价值的变量,初始为 0

    # 遍历每种物品
    for i, (price, weight) in enumerate(goods):
        if w >= weight:
            # 如果背包容量足够放下当前物品,则将整件物品放入背包
            m[i] = 1.0
            total_price += price  # 增加物品的总价值
            w -= weight  # 减少背包剩余容量
        else:
            # 如果背包容量不足以放下整个物品,则只放入物品的一部分
            m[i] = w / weight  # 计算放入的比例
            total_price += m[i] * price  # 增加按比例计算的物品价值
            w = 0  # 背包容量用尽
            break  # 背包已满,停止处理其他物品

    return total_price, m  # 返回总价值和每种物品的选择比例


# 示例用法
goods = [(60, 10), (120, 30), (100, 20)]
goods.sort(key=lambda x: x[0] / x[1], reverse=True)  # 按价值重量比降序排序物品
print(fractional_backpack(goods, 50))  # 输出:最大化价值和每种物品的选择比例

3 拼接最大数字问题

在这里插入图片描述

# 数字拼接问题也是贪心算法
a = '96'
b = '87'
res = a + b if a > b else b + a

a = '128'
b = '1286'
res = a + b if a + b > b + a else b + a

实现

from functools import cmp_to_key


def xy_cmp(x: str, y: str) -> int:
    """
    自定义比较函数,用于比较两个字符串 x 和 y 在不同顺序下拼接的结果。

    :param x: 第一个字符串
    :param y: 第二个字符串
    :return: 如果 x + y < y + x 返回 1(表示 y 应排在前面),
             如果 x + y > y + x 返回 -1(表示 x 应排在前面),
             否则返回 0(表示 x 和 y 顺序不变)。
    """
    if x + y < y + x:
        return 1  # y 应该排在 x 前面
    elif x + y > y + x:
        return -1  # x 应该排在 y 前面
    else:
        return 0  # 保持原有顺序


def number_join(li: list) -> str:
    """
    将一组数字组成一个最大可能的数字,数字之间的顺序由自定义的比较规则决定。

    :param li: 包含多个整数的列表
    :return: 拼接后的最大数字(字符串形式)
    """
    # 将整数列表中的每个数字转换为字符串,以便后续拼接操作
    li = list(map(str, li))

    # 使用自定义的比较函数 `xy_cmp` 对字符串列表进行排序
    li.sort(key=cmp_to_key(xy_cmp))

    # 将排序后的字符串列表拼接成一个大的字符串,并返回
    return ''.join(li)


li = [32, 94, 128, 1286, 6, 71]
print(number_join(li))  # 94716321286128

4 活动选择问题

在这里插入图片描述

在这里插入图片描述

from typing import List, Tuple

# 假设活动列表已经按结束时间排序
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11), (8, 12), (2, 14), (12, 16)]
# 使用 lambda 函数将活动按结束时间排序
activities.sort(key=lambda x: x[1])  # 按照每个活动的结束时间(元组的第二个元素)进行排序


def activities_selection(li: List[Tuple[int, int]]) -> List[Tuple[int, int]]:
    """
    选择最大兼容活动的贪心算法。

    该算法在给定的已排序活动列表中选择最大数量的互不冲突的活动,
    使得选择的活动之间没有时间重叠。

    :param li: 按结束时间排序的活动列表,每个活动由一个 (开始时间, 结束时间) 元组表示
    :return: 一个包含最大数量不冲突活动的列表,按活动的选择顺序排列
    """
    res = [li[0]]  # 初始化结果列表,将第一个活动加入到结果中

    # 从第二个活动开始遍历
    for i in range(1, len(li)):
        # 如果当前活动的开始时间大于或等于最后一个选择的活动的结束时间
        if li[i][0] >= res[-1][1]:
            res.append(li[i])  # 将当前活动加入结果列表中

    return res  # 返回包含最大数量不冲突活动的列表


print(activities_selection(activities))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2073095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于虚拟下垂控制的分布式电源并网建模仿真

针对并联逆变器间的环流和功率分配不均的问题&#xff0c;提出了一种基于改进虚拟阻抗的微电网逆变器下垂控制策略&#xff0c;对传统下垂控制算法的有功功率和无功功率进行分析&#xff0c;虚拟阻抗引入到电压电流双环控制策略。 在MATLAB中建立了逆变器并联运行的分布式仿真模…

【Qt】贪吃蛇

目录 贪吃蛇小游戏 一.项目介绍及演示 1. 项目介绍 2. 项目演示 3. 窗口介绍 3.1 游戏大厅窗口 3.2 游戏关卡选择窗口 3.3 游戏房间窗口 二、创建项目及资源配置 1. 创建项目&#xff08;QWidget&#xff09; ​编辑 2. 资源配置&#xff08;图片声音素材&#xff0…

文心快码助力项目实战开发

文章目录 前言支持的编程语言 Language安装方法使用方法 项目实践代码运行流程出行方案查询JSP 指令与标签库指令页面上下文路径设置表单部分查询结果显示部分 使用感受优点改进建议 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 文心快码Baidu Comat…

《黑神话:悟空》爆火,作为普通人,该怎么抓住这波风口赚到钱?

目录 一、游戏视频 1.1、游戏教程视频 1.2、游戏剧情视频 二、游戏直播 三、游戏视频出海 四、AI黑神话悟空 大家好&#xff0c;我是小奇&#xff0c;一名热衷于分享AI副业项目的普通博主。不管你是AI小白还是老手&#xff0c;我都能帮你轻松上手&#xff0c;用AI技术赚钱…

【C++ Primer Plus习题】4.7

问题: 解答: #include <iostream> #include <string> using namespace std;typedef struct _Pizza {string companyName;float diameter;float wieght; }Pizza;int main() {Pizza p;cout << "请输入披萨的公司名: ";getline(cin, p.companyName);…

uniapp+vue3的ifdef实现多端配置客服消息

在微信小程序预览&#xff0c;实现客服消息&#xff0c;因是个人版&#xff0c;不支持 button | uni-app官网 (dcloud.net.cn) 条件编译处理多端差异 | uni-app官网 (dcloud.net.cn) uni.makePhoneCall(OBJECT) | uni-app官网 (dcloud.net.cn) //my.vue <template> &l…

10大国产AI绘画软件,每一款都挺好用 ,你用过吗?

在这个科技与艺术交织的时代,AI绘画软件正以惊人的速度改变着我们的创作方式。今天,就让我们一起探索那些你绝不能错过的10大国产AI绘画神器,它们不仅让创作变得前所未有的简单高效,更让每一位艺术家和爱好者都能享受到创作的无限乐趣! 1️⃣触站A🎨——语音创作,未…

循环结构程序设计-找出指定数量学生的最高分

**7-1-1 #include <stdio.h>int main(){int n,score,max;scanf("%d",&n);max 0;for(int i0;i<n;i){scanf("%d",&score);if(score>max){max score;}}printf("%d",max);return 0; }

一文迅速上手 ESP32 bluedroid 蓝牙从机开发

前言 个人邮箱&#xff1a;zhangyixu02gmail.com该博客主要针对希望迅速上手 ESP32 蓝牙从机开发人员&#xff0c;因此&#xff0c;很多蓝牙技术细节知识并不会进行介绍&#xff0c;仅仅介绍我认为需要了解的 API 函数和回调内容。本文主要是基于gatt_server demo来微调进行进…

# ‘telnet‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

‘telnet’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 一、报错描述&#xff1a; 1、当使用 telnet 命令&#xff0c;连接本地 tomcat 的 8005 端口时报错。 2、报错解释 这个错误表明系统无法识别telnet命令&#xff0c;因为它不是内置命令&#xff0c;也没有…

跳马(华为od机考题)

一、题目 1.原题 马是象棋(包括中国象棋和国际象棋)中的棋子&#xff0c; 走法是每步直一格再斜一格&#xff0c; 即先横着或直着走一格&#xff0c;然后再斜着走一个对角线&#xff0c; 可进可退&#xff0c;可越过河界&#xff0c;俗称“马走‘日’字。 给顶m行n列的棋盘&…

人工智能在专业领域的斗争

介绍 ChatGPT 等大型语言模型 (LLM) 在用自然语言讨论一般话题的能力方面令人印象深刻。然而&#xff0c;他们在医学、金融和法律等专业领域却举步维艰。这是由于缺乏真正的理解&#xff0c;并且注重模仿而不是智力。 大语言模型正处于炒作的顶峰。由于能够用自然语言回答和讨…

“Docker中部署Kibana:步骤与指南“

博主这篇文章是跟Elasticsearch那篇文章是有关系的&#xff0c;建议大家先去看&#xff1a; 轻松上手&#xff1a;Docker部署Elasticsearch&#xff0c;高效构建搜索引擎环境_docker 启动 es-CSDN博客 这篇博文&#xff0c;还有镜像下载不下来的情况&#xff0c;大家可以去看…

攻破:重定向 缓冲区

文章目录 前言&#xff1a;认识读文件read认识重定向&&缓冲区重定向现象及分析&#xff1a;dup2的介绍&#xff1a; 缓冲区的引入&#xff1a;缓冲区的理解&#xff1a; 前言&#xff1a; ​ 从上一章开始&#xff0c;我们进入了文件IO的学习&#xff0c;认识了文件描…

浅谈C# RabbitMQ

一、基本介绍 RabbitMQ——Rabbit Message Queue的简写&#xff0c;但不能仅仅理解其为消息队列&#xff0c;消息代理更合适。 RabbitMQ 是一个由 Erlang 语言开发的AMQP&#xff08;高级消息队列协议&#xff09;的开源实现&#xff0c;其内部结构如下&#xff1a; RabbitMQ作…

今年秋招太吓人了。(20届,在得物做Java开发)

有个学弟来问我诉苦最近好忙好累&#xff0c;说竞争压力特别大&#xff0c;让我给点建议&#xff0c;要不要放弃实习闷头搞秋招&#xff0c;我才意识到时间太快了&#xff0c;想想我都毕业几年了&#xff0c;感慨颇深&#xff0c;整理一下我的求职经验和目前的心得吧&#xff0…

SpingBoot集成kafka-发送读取消息示例

SpingBoot集成kafka开发 kafka的几个常见概念 1、springboot和kafka对应版本&#xff08;重要&#xff09;2、创建springboot项目&#xff0c;引入kafka依赖2.1、生产者EventProducer2.2、消费者EventConsumer2.3、启动生产者的方法SpringBoot01KafkaBaseApplication2.4、appli…

监控电脑屏幕的软件叫什么?6款电脑屏幕监控软件分享!

监控电脑屏幕的软件可以帮助企业和家长监控电脑的使用情况&#xff0c;确保工作和学习的效率与安全。 以下是六款常用的电脑屏幕监控软件及其特点&#xff1a; 1. Keylogger 特点&#xff1a;专注于企业数据安全和员工上网行为管理。 功能&#xff1a;全面的屏幕监控、上网…

Redis持久化(RDB、AOF、混合持久化)

目录 1、持久化机制 &#xff08;1&#xff09;RDB &#xff08;2&#xff09;AOF 2、混合持久化 3、总结 ❓为什么需要持久化&#xff1f; Redis 是一个基于内存的键值存储系统&#xff0c;它提供了非常快的数据访问速度&#xff0c;因为它不需要像传统的磁盘存储那样进…

竞猜足球核心算法源码

需要实现的功能如下&#xff1a; 仅用于学习 竞猜足球核心算法源码 package com.lotterysource.portsadmin.service; import com.aliyun.oss.common.utils.DateUtil; import com.fasterxml.jackson.core.type.TypeReference; import com.lotterysource.portsadmin.dbprovid…