【算法训练营】:数字三角形,背包问题1,背包问题2(python实现)

news2025/1/20 22:36:41

数字三角形


时间限制:2 sec

空间限制:256 MB

问题描述

给定一个高度为 n 的“数字三角形”,其中第 i 行(1<=i<=n)有 i 个数。(例子如下图所示)

初始时,你站在“数字三角形”的顶部,即第一行的唯一一个数上。每次移动,你可以选择移动到当前位置正下方或者当前位置右下方的位置上。即如果你在 (i,j)(表示你在第i行从左往右数第j个数上,下同),你可以选择移动到 (i+1,j) 或 (i+1,j+1)。

你想让你经过的所有位置(包括起点和终点)的数字总和最大。求这个最大值。

输入格式

第一行一个正整数 n,表示数字三角形的大小。

第 2 行到第 n+1 行,第 i+1 行为 i 个用空格隔开的非负整数,描述数字三角形的第 i 行。

输出格式

一行一个整数,表示经过路径上数的最大总和。

样例输入

4
1
2 3
4 5 6
7 8 9 10

样例输出

20

样例解释

不停地向右下走即可。

数据范围

对于 50% 的数据,保证 n<=5。

对于 100% 的数据,保证 n<=1,000,保证数字三角形内的数不超过 10^6。

提示

[如果我们使用搜索算法,我们会在搜索时记录哪些信息呢?]

[当前到达的点的坐标、当前经过路径上数的总和!]

[总和显然是越大越好!]

[于是可以设计出状态:dp[i][j] 表示走到坐标为 (i,j) 的点时的最大总和。]

[很容易就可以设计出状态转移方程啦!]

代码实现

def max_path_sum(triangle):
    n = len(triangle)
    dp = [[0] * n for _ in range(n)]

    # 初始化第一行
    dp[0][0] = triangle[0][0]

    # 动态规划,计算最大总和
    for i in range(1, n):
        for j in range(i + 1):
            if j == 0:
                dp[i][j] = triangle[i][j] + dp[i-1][j]
            elif j == i:
                dp[i][j] = triangle[i][j] + dp[i-1][j-1]
            else:
                dp[i][j] = triangle[i][j] + max(dp[i-1][j], dp[i-1][j-1])

    # 返回最后一行的最大总和
    return max(dp[-1])

# 读取输入
n = int(input())
triangle = []
for _ in range(n):
    row = list(map(int, input().split()))
    triangle.append(row)

# 输出结果
result = max_path_sum(triangle)
print(result)





背包问题1


描述

n种物品,每种物品有相应的价值和体积,同时物品还分为两类,一类是“单个物品”,即该种物品只有一个;一类是“多个物品”,即该种物品有无限个。

现在你有一个体积为V的背包,那么该装些什么物品到背包里使得价值之和最大呢?

输入

第一行包含两个正整数n,V。

接下来n行,每行代表一种物品。每行的第一个数字表示该物品的种类(若为0表示“单个物品”,若为1表示“多个物品”),第二个数字表示该物品的价值,第三个数字表示该物品的体积。

输出

输出一个整数,表示最大的价值之和。

样例1输入

5 8
0 6 8
0 7 3
1 1 1
0 8 1
0 5 2

样例1输出

22

样例1解释

第三种物品有无限个,其余都是单个物品。

若我们放入物品1,则背包已经装满,此时价值和为6;

若我们放入物品2、4、5,背包所剩体积为8-3-1-2=2,此时价值和为7+8+5=20;

若我们放入8个物品3,背包装满,此时价值之和为8×1=8;

若我们放入物品2、4、5,再放两个物品3,则背包装满,此时价值和为7+8+5+2×1=22。

可以验证,最优答案就是22。

样例2

请查看下发文件内的sample2_input.txt和sample2_output.txt。

限制

对于30%的数据,n,V ≤ 20;

对于100%的数据,n,V ≤ 5000。

保证数据中所有的整数均为正整数,且不超过5000。

时间:6 sec

空间:512 MB

提示

[经典的01背包和完全背包问题。]

代码实现 

def knapsack(n, V, items):
    dp = [0] * (V + 1)

    for i in range(n):
        if items[i][0] == 0:  # 单个物品
            for j in range(V, items[i][2] - 1, -1):
                dp[j] = max(dp[j], dp[j - items[i][2]] + items[i][1])
        else:  # 多个物品,转化为完全背包问题
            for j in range(items[i][2], V + 1):
                dp[j] = max(dp[j], dp[j - items[i][2]] + items[i][1])

    return dp[V]

if __name__ == "__main__":
    n, V = map(int, input().split())
    items = []

    for _ in range(n):
        item = list(map(int, input().split()))
        items.append(item)

    result = knapsack(n, V, items)
    print(result)

背包问题2


描述

n个物品,每个物品有一个体积v和价值w。现在你要回答,把一个物品丢弃后,剩下的物品装进一个大小为V的背包里能得到的最大价值是多少。

输入

输入的第一行包含一个正整数n(n ≤ 5000)。

接下来n行,每行包含两个正整数v和w(v,w ≤ 5000),分别表示一个物品的体积和价值。

接下来一行包含一个正整数q(q ≤ 5000),表示询问个数。

接下来q行,每行包含两个正整数V和x(V ≤ 5000,x ≤ n),表示询问将物品x丢弃以后剩下的物品装进一个大小为V的背包能得到的最大价值。

输出

输出q行,每行包含一个整数,表示询问的答案。

样例1输入

3
3 5
2 2
1 2
3
3 1
3 2
3 3

样例1输出

4
5
5

样例1解释

有3个物品,第一个物品的体积为3、价值为5,第二个物品体积为2、价值为2,第三个物品体积为1、价值为2。

有3个询问:

第一个询问是问去掉1物品后剩下的2、3物品填进一个大小为3的背包能得到的最大价值。显然2、3物品都是可以放进背包的,所以最大价值为2+2=4。

第二个询问是问去掉2物品后剩下的1、3物品填进一个大小为3的背包能得到的最大价值。若我们填3物品,我们只能得到价值2;若我们填1物品,则可以得到价值5。所以最大价值为5。

第三个询问我们同样也是填1物品,最大价值为5。

样例2

请查看下发文件内的sample2_input.txt和sample2_output.txt。

限制

对于30%的数据,n,q,v,V,w ≤ 10;

对于50%的数据,n,q,v,V,w ≤ 200。

时间:10 sec

空间:512 MB

提示

[我们可以预处理“前缀背包”、“后缀背包”,然后询问时做“背包合并”的操作。]

代码实现 

def get_answer(n, vw, q, queries):
    v = [-1] + [vw[i][0] for i in range(n)]
    w = [-1] + [vw[i][1] for i in range(n)]

    d = [[0] * 5005 for _ in range(5005)]
    for i in range(1, n + 1):
        for V in range(v[i]):
            d[i][V] = d[i - 1][V]
        for V in range(v[i], 5001):
            d[i][V] = max(d[i - 1][V], d[i - 1][V - v[i]] + w[i])

    f = [[0] * 5005 for _ in range(5005)]
    for i in range(n, 0, -1):
        for V in range(v[i]):
            f[i][V] = f[i + 1][V]
        for V in range(v[i], 5001):
            f[i][V] = max(f[i + 1][V], f[i + 1][V - v[i]] + w[i])

    ans = []
    for query in queries:
        V, x = query
        mx = 0
        for i in range(V + 1):
            mx = max(mx, d[x - 1][i] + f[x + 1][V - i])
        ans.append(mx)

    return ans

if __name__ == "__main__":
    n = int(input())
    vw = [list(map(int, input().split())) for _ in range(n)]
    q = int(input())
    queries = [list(map(int, input().split())) for _ in range(q)]

    ans = get_answer(n, vw, q, queries)

    for i in ans:
        print(i)

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

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

相关文章

leetCode刷题 4.寻找两个正序数组的中位数

目录 1. 思路 2. 解题方法 3. 复杂度 4. Code 题目&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; 输入&…

SOC设计:关于时钟门控的细节

有如下几个信号 输入信号 1、同步后的rstnsync_clk 2、时钟&#xff1a;clk 3、test_mode 4、软件控制信号&#xff1a;clk_sub_en 输出信号 1、clk_sub 功能&#xff1a;软件配置的使能信号clk_sub_en经过时钟clk 2拍同步处理后产生clk 域下的enable信号&#xff0c;然…

flink重温笔记(十一):Flink 高级 API 开发——flink 四大基石之 Checkpoint(详解存储后端)

Flink学习笔记 前言&#xff1a;今天是学习 flink 的第 11 天啦&#xff01;学习了 flink 四大基石之 Checkpoint &#xff08;检查点&#xff09;&#xff0c;主要是解决大数据领域持久化中间结果数据&#xff0c;以及取消任务&#xff0c;下次启动人可以恢复累加数据问题&…

【LeetCode】升级打怪之路 Day 15:二叉树解题的思维模式 —— 遍历、分解问题

今日题目&#xff1a; 226. 翻转二叉树101. 对称二叉树114. 二叉树展开为链表 目录 LC 226. 翻转二叉树 【easy】LC 101. 对称二叉树 ⭐⭐⭐LC 114. 二叉树展开为链表 ⭐⭐⭐ 今天的题目主要是对二叉树递归遍历的应用&#xff0c;东哥带你刷二叉树&#xff08;思路篇&#xff0…

砝码称重 蓝桥杯

在C中&#xff0c;fabs()和abs()都用于计算数字的绝对值&#xff0c;但它们之间有一些区别。 fabs(double x)&#xff1a;计算浮点数x的绝对值&#xff0c;返回一个double类型的结果。 abs(int x)&#xff1a;计算整数x的绝对值&#xff0c;返回一个int类型的结果。 数组的默…

航天民芯一级代理 MT3608 MT3608L 升压转换器 1.2MHZ

MT3608/MT3608L是恒定频率的6引脚SOT23电流模式升压转换器&#xff0c;适用于小型、低功耗应用。MT3608在1.2MHz&#xff0c;允许使用微小、低成本的频率高度不超过2mm的电容器和电感器。内部软启动可实现较小的浪涌电流和延长电池寿命。MT3608具有自动切换到脉冲的功能轻负载下…

【控制台警告】npm WARN EBADENGINE Unsupported engine

今天用webpack下载几个loader依赖&#xff0c;爆出了三个警告&#xff0c;大概的意思就是本地安装的node和npm的版本不是很匹配&#xff1f; 我的解决思路是&#xff1a; 先检查node和npm版本 然后去官网查找版本的对应 靠&#xff0c;官网404 Node.js (nodejs.org) 就找到…

Conda快速安装的解决方法(Mamba安装)

如果你的Conda安装了&#xff0c;你可能会发现一个问题&#xff0c;就是使用Conda install 安装某个软件时&#xff0c;会特别慢&#xff0c;这时候呢&#xff1f;你会上网去搜&#xff0c;然后大家解决的方法呢。一是告诉你镜像可以下载快一点&#xff0c;二是&#xff0c;Mam…

Sentinel 规则持久化,基于Redis持久化【附带源码】

B站视频讲解 学习链接&#x1f517; 文章目录 一、理论二、实践2-1、dashboard 请求Redis2-1-1、依赖、配置文件引入2-1-2、常量定义2-1-3、改写唯一id2-1-4、新Provider和Publisher2-1-5、改写V2 2-2、应用服务改造2-2-1、依赖、配置文件引入2-2-2、注册监听器 三、源码获取3…

keycloak18.0.0==源码编译打包

参照官方文档building.md mvn -Pdistribution -pl distribution/server-dist -am -Dmaven.test.skip clean install 报错 ---------- [ERROR] Failed to execute goal com.github.eirslett:frontend-maven-plugin:1.12.0:npm (npm-install-common) on project keycloak-theme…

MySQL存储过程2——if、case、while、repeat、loop、cursor、handler

1、if用作条件判断 1.1、语法结构 IF 条件1 THEN... ELSEIF 条件2 THEN... ELSE... END IF; 在if条件判断的结构中&#xff0c;Else if结构可以有多个&#xff0c;也可以没有。Else结构可以有&#xff0c;也可以没有 1.2、示例 根据定义的分数score变量&#xff0c;判断当…

mysql学习笔记8——常用5个内置方法

1count 对查询内容进行计数&#xff0c;并返回结果 2as as可以将查询出来结果赋予新名字 3sum sum可以查询某字段特定条件下的和值 4concat concat可以将多列数据合并成一列&#xff0c;只要concat&#xff08;&#xff09;即可 5group_concat group_concat可以把多列…

Linux|终端管理|如何踢掉操作系统内的用户

一&#xff0c; 关于终端的一些基本概念 tty、pty 和 pts 是在类 Unix 系统&#xff08;包括 Linux&#xff09;中与终端交互相关的概念。它们各自代表不同的方面&#xff0c;并且有着密切的关联。 tty (Teletype) tty 原指老式的电传打字机&#xff0c;后来泛指任何类型的终…

Echarts 配置项 series 中的 data 是多维度

文章目录 需求分析 需求 如下图数据格式所示&#xff0c;现要求按照该格式进行绘制折线图 分析 在绘制折线图时&#xff0c;通常我们的 series 中的 data 数据是这样的格式 option {title: {text: Stacked Area Chart},tooltip: {trigger: axis,axisPointer: {type: cross…

内容管理平台用这几个就够了,简单又好用

对于大多数企业和自由职业者来说&#xff0c;选择合适的内容管理平台已经成为一种必备的技能。良好的内容管理平台可以赋能你的团队&#xff0c;让你们更好地协作、管理和分享内容。不管你是要发布博客文章&#xff0c;还是需要管理复杂的项目文档&#xff0c;都可以通过内容管…

华为OD机试 - 疫情扩散时间计算 - 矩阵(Java 2024 C卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&am…

图论 - DFS深度优先遍历、BFS广度优先遍历、拓扑排序

文章目录 前言Part 1&#xff1a;DFS&#xff08;深度优先遍历&#xff09;一、排列数字1.题目描述输入格式输出格式数据范围输入样例输出样例 2.算法 二、n皇后问题1.问题描述输入格式输出格式数据范围输入样例输出样例 2.算法 三、树的重心1.问题描述输入格式输出格式数据范围…

Ubuntu 下使用 Pybind11 实现 C++ 调用 Python 接口的示例

Pybind11 是一个轻量级的库&#xff0c;它提供了在 C 中无缝集成 Python 代码的能力。使用 Pybind11&#xff0c;你可以很容易地从 C 调用 Python 代码&#xff0c;反之亦然。下面我将通过一个简单的例子来展示如何在 Ubuntu 系统上使用 Pybind11 从 C 调用 Python 接口。 安装…

嵌入式常见概念介绍

什么是ARM&#xff1a; Advanced RISC Machines 先进RISC机器 嵌入式系统自诞生起就分为两条路&#xff1a; RISC&#xff1a;精简指令集计算机&#xff0c;如ARM&#xff0c;所有指令长度一致&#xff0c;指令数量较少 CISC&#xff1a;复杂指令集计算机&#xff0…

git 如何将多个提交点合并为一个提交点 commit

文章目录 核心命令详细使用模式总结示例 核心命令 git merge branch2 是将分支branch2的提交点合并到本地当前分支。 而在执行这条命令的时候&#xff0c;加一个选项--squash就表示在合并的时候将多个提交点合并为一个提交点。 git merge --squash branch2 先看squash单词的意…