贪心算法---背包问题(物品可以分割问题)

问题背景:

有一天,阿里巴巴赶着一头毛驴上山砍柴。砍好柴准备下山时,远处突然出现一股烟尘,弥漫着直向上空飞扬,朝他这儿卷过来,而且越来越近。靠近以后,他才看清原来是一支马队,他们共有四十人,一个个年轻力壮、行动敏捷。一个首领模样的人背负沉重的鞍袋,从丛林中一直来到那个大石头跟前,喃喃地说道:“芝麻,开门吧!”随着那个头目的喊声,大石头前突然出现一道宽阔的门路,于是强盗们鱼贯而入。阿里巴巴待在树上观察他们,直到他们走得无影无踪之后,才从树上下来。他大声喊道:“芝麻,开门吧!”他的喊声刚落,洞门立刻打开了。他小心翼翼地走了进去,一下子惊呆了,洞中堆满了财物,还有多得无法计数的金银珠宝,有的散堆在地上,有的盛在皮袋中。突然看见这么多的金银财富,阿里巴巴深信这肯定是一个强盗们数代经营、掠夺所
积累起来的宝窟。为了让乡亲们开开眼界,见识一下这些宝物,他想一种宝物只拿一个,如果太重就用锤子凿开,但毛驴的运载能力是有限的,怎么才能用驴子运走最大价值的财宝分给穷人呢? 阿里巴巴陷入沉思中……

问题分析:

假设山洞中有 n 种宝物,每种宝物有一定重量 w 和相应的价值 v,毛驴运载能力有限,
只能运走 m 重量的宝物,一种宝物只能拿一样,宝物可以分割。那么怎么才能使毛驴运走宝物的价值最大呢?
每次选取单位重量价值最大的宝物,也就是说每次选择性价比(价值/重量)最高的宝物,如果可以达到运载重量 m,那么一定能得到价值最大

算法设计:

(1)数据结构及初始化。将 n 种宝物的重量和价值存储在结构体 back(包含重量、价
值、性价比 3 个成员)中,同时求出每种宝物的性价比也存储在对应的结构体 back中,将其按照性价比从高到低排序。采用 sum 来存储毛驴能够运走的最大价值,初始化为 0。
(2)根据贪心策略,按照性价比从大到小选取宝物,直到达到毛驴的运载能力。每次选
择性价比高的物品,判断是否小于 c(毛驴运载能力),如果小于 c,则放入sum(已放入物品的价值)加上当前宝物的价值,c减去放入宝物的重量;如果不小于 c,则取该宝物的一部分 c* proportion[i],c=0,程序结束。c减少到 0,则 sum 得到最大值。

在性价比排序的基础上,进行贪心算法运算。如果剩余容量比当前宝物的重量大,则可
以放入,剩余容量减去当前宝物的重量,已放入物品的价值加上当前宝物的价值。如果剩余容量比当前宝物的重量小,表示不可以全部放入,可以切割下来一部分(正好是剩余容量),然后令剩余容量乘以当前物品的单位重量价值,已放入物品的价值加上该价值,即为能放入宝物的最大价值。

测试数据:

输入:
6 19 //宝物数量,驴子的承载重量
2 8 //第 1 个宝物的重量和价值
6 1 //第 2 个宝物的重量和价值
7 9
4 3
10 2
3 4

输出:
24.6

代码如下:

#include <iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;struct back{double weight;//重量double value;//价值double proportion;//性价比
}a[999];bool beyond(back a,back b){return a.proportion >b.proportion;//性价比由大到小排序
}int main()
{int number;//珠宝的种类double sum=0.0;//总价值double c;//驴最大载重量cin>>number>>c;for(int i=0;i<number;i++){//以次输入数据scanf("%lf",&a[i].weight);scanf("%lf",&a[i].value);a[i].proportion = a[i].value / a[i].weight;}sort(a,a+number,beyond);//按性价比由大到小排序for(int j=0;j<number;j++){if(c>=a[j].weight){//宝物的重量小于或等于驴的载重量c-=a[j].weight;//装上该宝物之后,驴的剩余载重量sum+=a[j].value;//宝物的价值}else{//宝物的重量大于驴的载重量sum+= c * a[j].proportion;//分割宝物break;}}printf("%.1lf\n",sum);cout<<sum;return 0;
}

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

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

相关文章

同步---信号量

信号量1 信号量2 驱动程序和测试程序3 内核的具体实现总结1 信号量 Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已经被占用的信号量时&#xff0c;信号量会将其放到一个等待队列&#xff0c;然后让其睡眠&#xff0c;这时处理器去执行其他代码。当持有信号量的进…

Java Float类floatToIntBits()方法与示例

Float类floatToIntBits()方法 (Float class floatToIntBits() method) floatToIntBits() method is available in java.lang package. floatToIntBits()方法在java.lang包中可用。 floatToIntBits() method follows IEEE 754 floating-point standards and according to standa…

解释三度带和六度带的概念以及各坐标系如何定义

★ 地形图坐标系&#xff1a;我国的地形图采用高斯&#xff0d;克吕格平面直角坐标系。在该坐标系中&#xff0c;横轴&#xff1a;赤道&#xff0c;用&#xff39;表示&#xff1b;纵轴&#xff1a;中央经线&#xff0c;用&#xff38;表示&#xff1b;坐标原点&#xff1a;中央…

0-1背包问题(物品不可分割)

问题背景&#xff1a; 所谓“钟点秘书”&#xff0c;是指年轻白领女性利用工余时间为客户提供秘书服务&#xff0c;并按钟点收取酬金。“钟点秘书”为客户提供有偿服务的方式一般是&#xff1a;采用电话、电传、上网等“遥控”式 服务&#xff0c;或亲自到客户公司处理部分业务…

算法---KMP算法

字符串1 KMP算法状态机概述构建状态转移1 KMP算法 原文链接&#xff1a;https://zhuanlan.zhihu.com/p/83334559 先约定&#xff0c;本文用pat表示模式串&#xff0c;长度为M&#xff0c;txt表示文本串&#xff0c;长度为N&#xff0c;KMP算法是在txt中查找子串pat&#xff0…

cache初接触,并利用了DataView

我们在写代码的时候,如果数据控件要获得数据,一般方法,Conn.Open();OleDbCommand cmd;cmd new OleDbCommand(sql, Conn);GridView1.DataSource dbcenter.accessGetDataSet(sql);GridView1.DataBind();Conn.close();但如果多个数据控件要绑定数据,则比较频繁打开数据库,效率一…

Java ByteArrayInputStream reset()方法及示例

ByteArrayInputStream类reset()方法 (ByteArrayInputStream Class reset() method) reset() method is available in java.util package. reset()方法在java.util包中可用。 reset() method is used to reset this ByteArrayInputStream to the last time marked position and …

回文数猜想

问题描述&#xff1a; 一个正整数&#xff0c;如果从左向右读&#xff08;称之为正序数&#xff09;和从右向左读&#xff08;称之为倒序数&#xff09;是一样的&#xff0c;这样的数就叫回文数。任取一个正整数&#xff0c;如果不是回文数&#xff0c;将该数与他的倒序数相加…

文件上传 带进度条(多种风格)

文件上传 带进度条 多种风格 非常漂亮&#xff01; 友好的提示 以及上传验证&#xff01; 部分代码&#xff1a; <form id"form1" runat"server"><asp:ScriptManager ID"scriptManager" runat"server" EnablePageMethods&quo…

同步---自旋锁

1 自旋锁的基本概念 自旋锁最多只能被一个可执行线程持有&#xff0c;如果一个执行线程试图获得一个已经被使用的自旋锁&#xff0c;那么该线程就会一直进行自旋&#xff0c;等待锁重新可用。在任何时刻&#xff0c;自旋锁都可以防止多余一个的执行线程同时进入临界区。 Linu…

实习日志----4.播放时段参数设置

由于客户在下发广告时&#xff0c;一则广告可在多个时段播放&#xff0c;这就需要设置多个播放时段的参数。 但在这种情况下&#xff0c;我并不知道用户每次需要下发几个时段&#xff0c;所以前台不能设定死。 因此我要实现这么一个功能&#xff0c;让用户根据自己的需要来动态…

线性插值算法实现图像_C程序实现插值搜索算法

线性插值算法实现图像Problem: 问题&#xff1a; We are given an array arr[] with n elements and an element x to be searched amongst the elements of the array. 给定一个数组arr []&#xff0c;其中包含n个元素和一个要在该数组的元素中搜索的元素x 。 Solution: 解&…

hdu 1197

地址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1197 题意&#xff1a;求一个数转换成10&#xff0c;12&#xff0c;16进制后各个位上的数的和是否相等。 mark&#xff1a;模拟进制转换。 代码&#xff1a; #include <stdio.h>int zh(int a, int n) {int su…

linux系统编程---线程总结

线程总结1 线程的实现线程创建线程退出线程等待线程清理2 线程的属性线程的分离线程的栈地址线程栈大小线程的调度策略线程优先级3 线程的同步互斥锁读写锁条件变量信号量线程是系统独立调度和分配的基本单位。同一进程中的多个线程将共享该进程中的全部系统资源&#xff0c;例…

博客上一些项目相关源码链接

GitHub&#xff1a;https://github.com/beyondyanyu/Sayingyy

重新开启Ctrl+Alt+Backspace快捷键

UBUNTU老用户知道CtrlAltBackspace这个快捷键是用来快速重启X的在9.04中被默认关闭了&#xff0c;那如何来打开它呢&#xff1f;在终端中输入&#xff1a;sudo gedit /etc/X11/xorg.conf在其中加入&#xff1a;Section “ServerFlags”Option “DontZap” “false”EndSection退…

Java LocalDate类| 带示例的getDayOfYear()方法

LocalDate类的getDayOfYear()方法 (LocalDate Class getDayOfYear() method) getDayOfYear() method is available in java.time package. getDayOfYear()方法在java.time包中可用。 getDayOfYear() method is used to get the day-of-year field value of this LocalDate obje…

火腿三明治定理

定理&#xff1a;任意给定一个火腿三明治&#xff0c;总有一刀能把它切开&#xff0c;使得火腿、奶酪和面包片恰好都被分成两等份。 而且更有趣的是&#xff0c;这个定理的名字真的就叫做“火腿三明治定理”&#xff08;ham sandwich theorem&#xff09;。它是由数学家亚瑟•斯…

如何给Linux操作系统(CentOS 7为例)云服务器配置环境等一系列东西

1.首先&#xff0c;你得去购买一个云服务器&#xff08;这里以阿里云学生服务器为例&#xff0c;学生必须实名认证&#xff09; 打开阿里云&#xff0c;搜索学生服务器点击进入即可 公网ip为连接云服务器的主机 自定义密码为连接云服务器是需要输入的密码 购买即可 点击云服…

Linux系统编程---I/O多路复用

文章目录1 什么是IO多路复用2 解决什么问题说在前面I/O模型阻塞I/O非阻塞I/OIO多路复用信号驱动IO异步IO3 目前有哪些IO多路复用的方案解决方案总览常见软件的IO多路复用方案4 具体怎么用selectpollepolllevel-triggered and edge-triggered状态变化通知(edge-triggered)模式下…