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

C/C++语言100题练习计划 83——背包问题(贪心算法实现)

名人说:故立志者,为学之心也;为学者,立志之事也。—— 王阳明
进度:C/C++语言100题练习计划专栏,目前83/100

🥇C/C++语言100题练习专栏计划目的:巩固练习C/C++语言,增强上机、动手实践能力,交流学习!

一、问题呈现

1.问题描述

Problem Description
假设山洞中有n种宝物,每种宝物有一定重量w和相应的价值v,毛驴运载能力有限,只能运走m重量的宝物,一种宝物只能拿一样,宝物可以分割。那么怎么才能使毛驴运走宝物的价值最大呢?

2.输入输出

Input

第一行:宝物数量n,以及毛驴的承载重量m
n行:每个宝物的重量w和相应的价值v

Output

装入总的宝物的最大价值

3.测试样例

Sample Input 1

6 19
2 8
6 1
7 9
4 3
10 2
3 4

Sample Output 1

24.6

Sample Input 2

5 12
2 3
4 2
1 4
5 5
4 6

Sample Output 2

18

二、源码实现

#include <iostream>
#include <algorithm>
using namespace std;
const int Maxn=1e6+5;

//宝物结构体
struct treasure {
	double w;  //每个宝物的重量
	double v;  //每个宝物的价值
	double p;  //每个宝物的性价比
}t[Maxn];

//排序比较函数
bool cmp(treasure a, treasure b)
{
	return a.p > b.p;  //根据宝物的单位价值从大到小排序(降序排序)
}

//主函数
int main()
{
	//n 表示有n个宝物
	int n;  
	//m 表示毛驴的承载能力
	double m;  
	
	//输入宝物数量n及毛驴的承载能力m
	cin>>n>>m;

	//输入每个宝物的重量及价值
	for(int i=0; i<n; i++)
	{
		cin>>t[i].w>>t[i].v;
		t[i].p=t[i].v/t[i].w;  //每个宝物单位价值=其价值/其重量
	}
	
	//降序排序
	sort(t,t+n,cmp);
	
	//sum 表示贪心记录运走宝物的价值之和
	double sum = 0.0;  
	
	//按照排好的顺序,循环执行贪心策略
	for(int i=0; i<n; i++)  
	{
		//如果宝物的重量小于毛驴的运载能力
		if( m > t[i].w)  
		{
			m -= t[i].w;
			sum += t[i].v;
		}
		//如果宝物的总量大于毛驴的承载能力
		else 
		{
			//进行宝物切割,切割一部分(m重量),正好达到毛驴称重
			sum += m * t[i].p;  
			break;
		}
	}
	
	//输出装入总的宝物的最大价值
	cout<<sum<<endl;
	
	return 0;
}

★关于本题思路及贪心算法(+补充)

1️⃣本题思路简述
本题大概的思路就是,首先为了使m重量里的所有物品的价值最大,可以借助贪心思想,每次取剩下物品里面性价比最高的物品,这样可以使得在相同重量条件下比选其他物品所得到的价值更大,因此采用贪心策略能得到最优解。(物品可分割的装载问题称为背包问题,物品不可分割的装载问题称为0-1背包问题)。

2️⃣贪心算法
①思想解释
在《算法导论》书籍中,有这样一句话:“一个贪心算法总是做出当前最好的选择,也就是说,它期望通过局部最优选择从而得到全局最优的解决方案。
这句话,怎么理解呢?个人来看,其实就好比,我们走路会遇到很多的十字路口,这个时候我们就面临选择,那么哪个对于当前是最优的,我们要考虑到交通路况、目的地等多种因素,综合来看,当前最好的选择是哪一个,就走哪条路,下一个十字路口也是这样,直至到达目的地。

②使用贪心算法求解的两个重要特性
a.贪心选择
所谓贪心选择性质是指原问题的整体最优解可以通过一系列局部最优的选择得到。应用同一规则,将原问题变为一个相似的但规模更小的子问题,而后的每一步都是当前最佳的选择。这种选择依赖于已作出的选择,但不依赖于未做出的选择。

b.最优子结构
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。
// 如果满足这两个性质就可以考虑使用贪心算法了。(这两个性质划重点)

★补充:
③贪心算法优缺点
优点简单,高效,省去了为了找最优解可能需要穷举操作,通常作为其它算法的辅助算法来使用;
缺点不从总体上考虑其它可能情况,每次选取局部最优解,不再进行回溯处理,所以很少情况下得到最优解。

其实如果你看到了这里,还要注意一点:物品可分割的装载问题称为背包问题,物品不可分割的装载问题称为0-1背包问题。背包问题和0-1背包问题是不一样的。本题你可以判断出,它是一个背包问题,可分割。

三、测试结果

6 19
2 8
6 1
7 9
4 3
10 2
3 4
24.6

--------------------------------
Process exited after 1.588 seconds with return value 0
请按任意键继续. . .

Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder)
如果对大家有帮助的话,希望大家能多多点赞+关注!这样我动力会更足哦! ღ( ´・ᴗ・` )比心

相关文章:

  • JS:数组类型及常用的方法使用
  • Oracle-job跑批变慢案例
  • java/php/python在线求助救援网站vue+elementui
  • Vivado关联Vscode,解决Vscode自动保存和卡顿问题
  • Java基础用Date类编写万年历
  • 前端面试题2
  • 通信算法之七十八:无人机反制—精华总结
  • Leetcode--剑指Offer
  • 【web-攻击应用程序框架】(12.2)共享主机与服务提供商:攻击、保障
  • JavaScript-操作BOM对象
  • position定位总结+元素选择器+window对象的子对象
  • MySQL什么情况会导致索引失效?
  • 力扣(122.1049)补7.29
  • 【数据结构与算法】链表
  • Python中的依赖注入
  • 03Go 类型总结
  • Android 控件背景颜色处理
  • avalon2.2的VM生成过程
  • Git的一些常用操作
  • Hexo+码云+git快速搭建免费的静态Blog
  • jdbc就是这么简单
  • leetcode46 Permutation 排列组合
  • MaxCompute访问TableStore(OTS) 数据
  • Mocha测试初探
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • Spring Boot MyBatis配置多种数据库
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 思考 CSS 架构
  • 算法-插入排序
  • 算法系列——算法入门之递归分而治之思想的实现
  • 小而合理的前端理论:rscss和rsjs
  • 用jQuery怎么做到前后端分离
  • 关于Android全面屏虚拟导航栏的适配总结
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • #pragma pack(1)
  • #Z2294. 打印树的直径
  • #大学#套接字
  • #单片机(TB6600驱动42步进电机)
  • #在 README.md 中生成项目目录结构
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • %check_box% in rails :coditions={:has_many , :through}
  • (11)MATLAB PCA+SVM 人脸识别
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (待修改)PyG安装步骤
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (三)docker:Dockerfile构建容器运行jar包
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)JAVA中的堆栈
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)winform之ListView
  • (转)大型网站架构演变和知识体系