2024-03-20:用go语言,自 01背包问世之后,小 A 对此深感兴趣。 一天,小 A 去远游,却发现他的背包不同于 01 背包,他的物品大致可分为 k 组。 每组中的物品只能选择1件,现在他想
2024-03-20:用go语言,自 01背包问世之后,小 A 对此深感兴趣。
一天,小 A 去远游,却发现他的背包不同于 01 背包,他的物品大致可分为 k 组。
每组中的物品只能选择1件,现在他想知道最大的利用价值是多少?
答案2024-03-20:
来自左程云。
大体步骤如下:
1.定义常量 MAXN 和 MAXM,分别表示物品数量和背包容量的最大值。
2.声明一个二维数组 arr 用于存储物品的重量、价值和组别信息。
3.声明一个一维数组 dp 用于记录每个容量下的最大利用价值。
4.获取输入信息,包括背包容量 m 和物品数量 n。
5.遍历n次,将物品的重量、价值和组别信息存入二维数组 arr。
6.根据物品的组别信息对二维数组 arr 进行排序。
7.初始化数组 dp,将所有元素设置为0。
8.使用动态规划算法计算最大利用价值。遍历每个组别的物品,对于每个容量 r,遍历当前组别的物品,如果容量 r 大于等于物品的重量,则更新 dp[r] 为当前物品的价值加上 dp[r-物品重量] 的最大值。
9.返回 dp[m],即背包容量为 m 时的最大利用价值。
10.打印结果。
总的时间复杂度是 O(nmlog(n)),其中 n 是物品数量,m 是背包容量。这是因为需要对二维数组 arr 进行排序,排序的时间复杂度是 O(nlog(n)),而计算最大利用价值的动态规划算法的时间复杂度是 O(nm)。
总的额外空间复杂度是 O(n),其中 n 是物品数量。这是因为需要使用数组 dp 来记录每个容量下的最大利用价值。
go完整代码如下:
package main
import (
"fmt"
"sort"
)
const MAXN = 1001
const MAXM = 1001
var arr = [MAXN][3]int{}
var dp = [MAXM]int{}
var m, n int
func compute() int {
for start, end := 0, 1; start < n; {
for end < n && arr[end][2] == arr[start][2] {
end++
}
for r := m; r >= 0; r-- {
for i := start; i < end; i++ {
if r >= arr[i][0] {
dp[r] = max(dp[r], arr[i][1]+dp[r-arr[i][0]])
}
}
}
start = end
end++
}
return dp[m]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func main() {
inputs := []int{45, 3,
10, 10, 1,
10, 5, 1,
50, 400, 2}
ii := 0
m = inputs[ii]
ii++
n = inputs[ii]
ii++
for i := 0; i < n; i++ {
arr[i][0] = inputs[ii]
ii++
arr[i][1] = inputs[ii]
ii++
arr[i][2] = inputs[ii]
ii++
}
sort.Slice(arr[:n], func(i, j int) bool {
return arr[i][2] < arr[j][2]
})
for i := 0; i <= m; i++ {
dp[i] = 0
}
fmt.Println(compute())
}
python完整代码如下:
# -*-coding:utf-8-*-
MAXN = 1001
MAXM = 1001
arr = [[0] * 3 for _ in range(MAXN)]
dp = [0] * MAXM
m, n = 0, 0
def compute():
start = 0
while start < n:
end = start + 1
while end < n and arr[end][2] == arr[start][2]:
end += 1
for r in range(m, -1, -1):
for i in range(start, end):
if r >= arr[i][0]:
dp[r] = max(dp[r], arr[i][1] + dp[r - arr[i][0]])
start = end
return dp[m]
def max(a, b):
return a if a > b else b
inputs = [45, 3,
10, 10, 1,
10, 5, 1,
50, 400, 2]
ii = 0
m = inputs[ii]
ii += 1
n = inputs[ii]
ii += 1
for i in range(n):
arr[i][0] = inputs[ii]
ii += 1
arr[i][1] = inputs[ii]
ii += 1
arr[i][2] = inputs[ii]
ii += 1
arr = arr[:n]
arr.sort(key=lambda x: x[2])
for i in range(m + 1):
dp[i] = 0
print(compute())
2024-03-20:用go语言,自 01背包问世之后,小 A 对此深感兴趣。 一天,小 A 去远游,却发现他的背包不同于 01 背包,他的物品大致可分为 k 组。 每组中的物品只能选择1件,现在他想的更多相关文章
- Java实现 LeetCode 560 和为K的子数组(某著名排序大法改编)
560. 和为K的子数组 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] ...
- Python Cookbook(第3版)中文版:15.20 处理C语言中的可迭代对象
15.20 处理C语言中的可迭代对象¶ 问题¶ 你想写C扩展代码处理来自任何可迭代对象如列表.元组.文件或生成器中的元素. 解决方案¶ 下面是一个C扩展函数例子,演示了怎样处理可迭代对象中的元素: s ...
- Java实现 LeetCode 713 乘积小于K的子数组(子集数量+双指针)
713. 乘积小于K的子数组 给定一个正整数数组 nums. 找出该数组内乘积小于 k 的连续的子数组的个数. 示例 1: 输入: nums = [10,5,2,6], k = 100 输出: 8 解 ...
- Java实现 LeetCode 698 划分为k个相等的子集(递归)
698. 划分为k个相等的子集 给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等. 示例 1: 输入: nums = [4, 3, 2, 3, ...
- 累加和为 K 的子数组问题
累加和为 K 的子数组问题 作者:Grey 原文地址: 博客园:累加和为 K 的子数组问题 CSDN:累加和为 K 的子数组问题 题目说明 数组全为正数,且每个数各不相同,求累加和为K的子数组组合有哪 ...
- 1077 互评成绩计算 (20 分)C语言
在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个最高分和一个最低分,剩下的分数取平 ...
- noip2017爆炸记——题解&总结&反省(普及组+提高组)
相关链接: noip2018总结 noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高 ...
- 35-Ubuntu-组管理-01-添加组/删除组/确认组信息
组管理 提示: 创建组/删除组的终端命令都需要sudo执行,标准用户没有权限! 序号 命令 作用 01 sudo groupadd 组名 添加组 02 sudo groupdel 组名 删除组 03 ...
- iOS之UITableView组头组尾视图/标题悬停
最近笔者在公司的iOS开发中,有一个iOS开发同事跑来问了两个问题:1.给UITableView设置了组头和组尾视图,但是一直显示不出来?2.UITableView的section的header和fo ...
- 《程序员代码面试指南》第七章 位运算 在其他数都出现k 次的数组中找到只出现一次的数
题目 在其他数都出现k 次的数组中找到只出现一次的数 java 代码 package com.lizhouwei.chapter7; /** * @Description: 在其他数都出现k 次的数组 ...
随机推荐
- ClickHouse-tgz安装步骤
一.什么是clickhouse ClickHouse是开源的列式存储数据库(DBMS),主要用于在线处理查询(OLAP),能够使用SQL查询实时生成数据分析报告. 下面介绍下安装clickhouse. ...
- K8S部署之VMWare网络拓扑踩坑
目录 背景 VMWare 虚拟网络 安装 Ubuntu Server 20.04 时遇到的网络问题 解决方法和解释 总结 背景 知乎上最近发现一篇好文 图解K8S(01):基于Ubuntu 20.04 ...
- 你应该知道的提升Visual Studio开发能力的5个技巧
如果你像我一样,或许你也沉迷于开发者工具.这就是我喜欢 Visual Studio 的原因之一--它有无数的生产力技巧. 这篇文章将展示五个这样的技巧,这些技巧对我每天的工作都有帮助.请注意,这些仅适 ...
- dotnet-cnblog tool 测试案例
这是测试donet-cnblog工具是否能将正常的Typora图片转换为博客园格式 测试1:本地图片导入 测试2:QQ截图 测试3:url https://pics3.baidu.com/feed/9 ...
- Host跨网段的ARP request
写得很清楚的文章:ARP协议在同网段及跨网段下的工作原理 对应的官方ARP文档:RFC 826 对文档的解读:详解RFC 826文档 ARP跨网段进行request包发送,需要先检测自身子网是否与对方 ...
- Docker 容器逃逸漏洞 (CVE-2020-15257)
漏洞详情 Docker发布一个容器逃逸漏洞,攻击者利用该漏洞可以实现容器逃逸,提升特权并破坏主机. containerd使用的抽象套接字仅使用UID做验证,即任意UID为0的进程均可访问此API. 当 ...
- file.deleteOnExit()与file.delete()的区别
之前踩过一个坑,下载过的文件在我第二次打开app的时候奇迹的找不到了.难道是没有下载成功?为此我特地查看了我的本地文件路径的目录.事实证明文件的确是下载到了本地路径下,但是第二次进入app的时候,路径 ...
- 什么是数据同步利器DataX,如何使用?
转载至我的博客 https://www.infrastack.cn ,公众号:架构成长指南 今天给大家分享一个阿里开源的数据同步工具DataX,在Github拥有14.8k的star,非常受欢迎,官网 ...
- VIM初使化
vim ~/.vimrc #设置编码 set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936 #显示行号 set number #一个tab为4个空格 ...
- 【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
问题描述 使用Azure Application Insights收集AKS中ASP.NET Core应用的监控数据,自动收集请求的Trace情况,用于分析单个请求在应用内部的耗时及处理事件情况,参考 ...