当前位置: 首页 > article >正文

趣味算法------单一背包问题(01背包问题)贪心算法解决

目录

​编辑

前言

例题

题目描述

输入输出格式

解题思路

具体代码

        C语言代码 

          python代码

总结


前言

        单一背包问题(0-1 Knapsack Problem)是组合优化中的一个经典问题,它可以形式化为:给定一组物品,每个物品都有一个重量和一个价值,目标是选择一些物品放入背包中,使得背包中物品的总价值最大,同时不超过背包的最大承重限制。在这个问题中,每个物品只能选择放或不放,不能分割。 

解决单一背包问题的方法包括动态规划、回溯算法和分支限界法等。动态规划是解决这类问题的常用方法,它通过构建一个二维数组来存储子问题的解,并使用状态转移方程来填充这个数组。状态转移方程通常表示为 dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]),其中 dp[i][j] 表示前 i 个物品放入容量为 j 的背包中所能获得的最大价值,w[i] 和 v[i] 分别表示第 i 个物品的重量和价值。 

在实际应用中,单一背包问题可以模拟旅行行李打包、投资组合选择、货物装载与运输、项目选择与管理、供应链管理、能源管理、课程安排和紧急救援物资分配等场景。 

例题

题目描述


有 N  件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi ,价值是 wi 。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入输出格式


输入格式
第一行两个整数N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi wi,用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式
一个非负整数,代表结果。

输入输出样例1
输入
4 5
1 2
2 4
3 4
4 5
输出
8

输入输出样例2
输入
1 2
2 2
输出
2

解题思路

  1. 初始化:首先,代码定义了背包的容量V和物品的数量N。然后,它为物品的重量和价值分配了动态数组weightsvalues,以及一个二维数组lst来存储动态规划过程中的状态值。

  2. 输入读取:代码使用scanf函数从标准输入读取物品的数量、背包容量以及每个物品的重量和价值。

  3. 动态规划填充:代码通过两层嵌套循环来填充动态规划数组lst。外层循环遍历物品,内层循环遍历背包的容量。对于每个容量和每个物品,代码检查当前物品是否可以放入背包中(即当前容量是否大于或等于该物品的重量)。如果可以,代码计算放入当前物品和不放入当前物品两种情况下的最大价值,并更新lst数组中相应位置的值。

  4. 结果输出:填充完成后,代码通过printf函数输出背包的最大价值,即lst[N][V]

具体代码

        C语言代码 

        

​
#include<stdio.h>
#include<stdlib.h>
#define maxlen 100
int main(void)
{
	int N, V;
	scanf("%d%d", &N, &V);
	int lst[maxlen][maxlen] = { 0 };
	int* weights = (int*)malloc(N * sizeof(int));
	int* values = (int*)malloc(V * sizeof(int));
	for (int i = 0; i < N; i++)
	{
		int s, r;
		scanf("%d%d", &s, &r);
		weights[i] = s;
		values[i] = r;
	}
	for(int i = 1;i<N+1;i++)
		for (int j = 1; j < V + 1; j++)
		{
			if (j < weights[i - 1])
				lst[i][j] = lst[i - 1][j];
			else
			{
				int datas1 = lst[i - 1][j];
				int datas2 = lst[i - 1][j - weights[i - 1]] + values[i - 1];
				
                if (datas1 > datas2)
					lst[i][j] = datas1;
				else
					lst[i][j] = datas2;
                
                lst[i][j]=(datas1>datas2)?datas1:datas2;
			}
		}
	printf("%d", lst[N][V]);
		
	return 0;
	
}

​

          python代码

N,V = [int(i) for i in input().split()]
lst = []
weights = []
values = []
for i in range(N):
    w,v = [int(i) for i in input().split()]
    weights.append(w)
    values.append(v)
for i in range(N+1):
    lst.append([0]*(V+1))
for i in range(1,N+1):
    for j in range(1,V+1):
        if j<weights[i-1]:
            lst[i][j] = lst[i-1][j]
        else:
            datas1 = lst[i-1][j]
            datas2 = lst[i-1][j-weights[i-1]]+values[i-1]
            lst[i][j] = max(datas1,datas2)
print(lst[N][V])

总结

        

单一背包问题是组合优化问题中的一个经典问题,它可以通过动态规划算法高效解决。在这个问题中,目标是选择一组物品放入背包中,使得背包的总价值最大,同时不超过背包的容量限制。动态规划算法通过构建一个二维状态数组来存储子问题的最优解,并通过状态转移方程递归地求解每个子问题,最终得到整个问题的最优解。

动态规划解决单一背包问题的关键在于定义合适的状态和状态转移方程。状态通常定义为dp[i][j]表示前i个物品放入容量为j的背包中所能获得的最大价值。状态转移方程为dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]),其中w[i]v[i]分别是第i个物品的重量和价值。如果当前背包容量不足以容纳第i个物品,则状态转移方程简化为dp[i][j] = dp[i-1][j]

动态规划算法的时间复杂度为O(N*V),其中N是物品的数量,V是背包的容量。空间复杂度也是O(N*V),但可以通过使用一维数组进行空间优化,将空间复杂度降低到O(V)

在实际应用中,动态规划不仅能够解决单一背包问题,还可以扩展到完全背包问题、多重背包问题等变体。动态规划的思想在解决这类优化问题时展现了其强大的能力,通过将大问题分解为小问题并存储子问题的解,动态规划避免了重复计算,提高了算法效率。


http://www.kler.cn/a/288755.html

相关文章:

  • 使用pdfjs加载多页pdf并实现打印
  • request爬虫库的小坑
  • Spring Cloud Contract快速入门Demo
  • SpringBoot(八)使用AES库对字符串进行加密解密
  • Stable Diffusion:照片转视频插件
  • wordpress搭建主题可配置json
  • 安防视频综合管理系统EasyCVR视频汇聚平台集群部署出现状态不同步的情况是什么原因?
  • 遥控器显示分别对应的无人机状态详解!!
  • VUE2.0 elementUI el-input-number 数据更新,视图不更新——基础积累
  • 使用idea快速创建springbootWeb项目(springboot+springWeb+mybatis-Plus)
  • 2.SpringBoot项目pom.xml文件配置
  • 【安卓面试】
  • 科学高效的FPGA编程方法
  • 从0到DevOps(1)-初步了解DevOps和容器
  • Nginx集成第三方负载均衡模块:配置指南与实践
  • 正则表达式模块re及其应用
  • 在K8s上运行GitHub Actions的自托管运行器
  • Swift 可选类型
  • 快速入门Pytorch
  • 搭子小程序开发,让社交更加有趣
  • AI赚钱成功案例|像素级拆解一键生成提示词 文生图 图生视频
  • Python 多目标跟踪-匈牙利算法
  • ArcGIS Pro SDK (十二)布局 7 组元素
  • Java算法之LRUCache缓存实现
  • 关于武汉芯景科技有限公司的A/D转换芯片XJ3021开发指南(兼容MCP3021)
  • 如何在已安装的最小化银河麒麟高级服务器操作系统上安装图形化界面