饮料供货

编程之美饮料供货:动态规划解法 #include #include #include using namespace std; struct Goods{ string name;//饮料的名字名字 int capacity;//单位饮料的容量,单位:L int maxNumber;//可供应饮料的最大数量,单位:个 int happiness;//对单位饮料的满意度 int purchaseNumber;// 阅读详情

一、问题:

 水房中有很多饮料,上班的人每天都去拿一些饮料,管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,他们会统计大家对每种饮料的满意程度。

从阿姨的统计数据中,我们知道了大家对每一种饮料的满意度。供应饮料还有如下限制:

首先供应的饮料,总容量为V。

其次每一种饮料的单个容量都是2的方幂,什么意思呢,比如说王老吉每瓶都是2的3次幂=8L的,可口可乐都是2的四次幂=16L的,等等。

最后一个限制就是每一种饮料的容量都是有上限的。

统计数据中用饮料的名字、容量、数量、满意度描述每一种饮料。

问题是让我们根据这个数据,去求得保证最大满意度的购买量呢?

二、分析:

我们先把这个问题数学化,假设供应的饮料的种类是n,用(Si,Vi,Ci,Hi,Bi)(对应饮料名字,单瓶容量,可能的最大数量(上限),满意度,实际购买量)来表示第i种饮料(i = 0,1,2,3,4.......)。那么我们根据上面的分析,得出,饮料总量为:

那么总体满意度是(满意度是针对每瓶的,那么总体满意度就是所有瓶的满意度的和):

。

接下来,再看看我们题目的要求怎样用数学公式表示出来,在满足条件

的基础之上,

求得。

解法一

书上再次采用了动态规划的方法进行求解,用Opt(V',i)表示从底i,i+1,i+2.........n-1 种饮料中,算出总容量为V’的方案中满意度之和的最大值。
因此,Opt(V,0)其实就是我们就要求的值,它代表的就是从0,1,2,3........n-1,总容量为V的方案之中满意度之和最大的值。
那么我们其实可以列出如下的推导公式:
这个公式的意思就是说:最优化的结果是=“选择k个第i种饮料的满意度+剩下部分不考虑第i种饮料的最优化结果”的最大值。
这种思想很好理解,接下来我们先附上代码,然后进行解释
int[V + 1][T + 1] opt;
int  Cal(int V, int type)
{
	if (type == T)
	{
		if (V == 0)
			return 0;
		else
			return -INF;
	}
	if (V < 0)
		return -INF;
	else if (V == 0)
		return 0;
	else if (opt[V][type] != -1)
		return opt[V][type];

	int ret = -INF;
	for (int i = 0; i <= C[type]; i++)
	{
		int temp = Cal(V - i*V[i], type + 1);
		if (temp != -INF)
		{
			temp += H[type] * i;
			if (temp > ret)
				ret = temp;
		}
	}
	return opt[V][type]=ret;
}
我们来看一下代码中是怎么实现的,首先要明白我们最终要求的结果是什么?我们要求的最终的结果是Cal(V,0),也就是说我们直接调用代码中Cal函数,传进去参数为v,o
然后我们接着看函数内部,前几行,代码中首先对type的值进行判断,看其是否等于T,然后又对V的大小进行判断,看其是否小于0,为什么要这样判断呢?原因等会再说,我们接着往下看,首先我们 令 ret = -INF是把其设置为无穷大,接着我们开始这个函数的重头戏了,也就是这个for循环,首先我们看它的i指的是什么意思呢?其实i代表的就是饮料的数量,也就是瓶数,i的限定大小就是其上限了,这个都不难理解,然后我们接着看for循环内部循环体,第一步,它先再次调用了自己函数本身,我们知道调用函数本身其实就是递归,没错,这就是递归,关键是你要明白为什么要这样递归,假设我们此时才是第一轮,那么我们此时的type是等于0的,i也是等于0的,那么在第一轮中代表我们把第0种饮料的数量设置为0的情况下,我们再去调用Cal函数,根据在写代码之前我们说的这个动态规划的思想,我们就必须把Cal函数的参数给更改一下,V就要变成总容量减去第0种饮料的容量,此时是0,type参数呢?此时我们已经把第0种饮料给固定了,接下来我们就是要从第1种饮料开始了呗,所以就把type+1.
接着我们继续,既然它又再次调用了自己,那么我们继续开Cal函数,从头看,此时我们再去看它判断的type ==T ,哎?随着它一次次的调用自己,你发现没,type总有达到T的时刻,千万注意:此时到达type=T不是说这一轮是对最后一种饮料进行分配,而是超出了最后一种,因为type 是从0开始的,这其实就是递归到了最深层,接下来该干什么了?返回呗!看此时的返回值如果V==0然后返回0,这个代表什么意思呢?就是说我们正好在分配第 T-1种饮料的时候,把V用完了,这代表什么,找到解了呗。
然后我们接着看这个对V的判断,说if (V<0)就直接返回-INF,什么意思呢?想一想,在我们不断的对每种饮料分配的过程中,我们发现V用超了,那代表什么意思?当然是没解呗!当然要返回-INF了,如果等于0呢?那么就是说当我们分配上一层的那种饮料的时候把V恰巧用完,这一层的饮料的满意度当然为0了,直接返回就行了。你再看还有一个else if,就是说V还没有用完,那就继续呗,把其值赋为-1,代表这种V这种type的饮料的情况还没有确定下来是否有解。
好了,接下来,我们再去看看for循环中的循环体,我们刚才说了调用自己的那个地方,我们接着往下看,注意:什么时候程序才会接着往下走呢?当然是递归有返回值了呗,就是下一层计算出来了我们要的temp,我们把这个temp和-INF去比较,如果是负无穷,就代表当前的情况是没解的,直接丢掉就行,如果不等于负无穷呢?代表有解,然后我们再根据当前层对type种饮料的分的数量,计算出这一层第type种的饮料贡献的满意度计算出来,然后和原来的temp去比较,其实就是和当前type种的饮料分配不同的数量的方案比较,保留最大的那个。
好了,其实我很罗嗦,但是我想说的是有些时候阅读代码还是很好的,能帮助你更加深刻的理解算法的精髓。

解法二、

书上还有一种解法,这个很巧妙。
它把不同种类的饮料的单个瓶的容量从小到大进行了排列,注意题目中给出每一种饮料的单个容量都是2的次幂。
那么,如果我们把总容量V去对2取余,如果得到的结果是1,那代表什么,就是说V是奇数,那么就是说2的次幂的饮料至少要有一瓶的,然后呢?我们就去查找单瓶容量为1L的饮料满意度为最高的。书上又说,如我们要买容量为2L的怎么办呢?我们找到2L中满意度最高的,然后再去找2个1L的满意度和最高的,然后二者进行比较,哪个高就用那个方案。

接下来就是我的思考了:
首先我先计算好,2L的能不能用1L的替代,4L的能不能用2L(注意此时结算2L的满意度的时候要考虑到其是否可以用1L的替代)的替代,8升的能不能用4L的替代。。。。。。
然后,我把V先去除以2,然后如果得出1,就代表1L的我一定要买一瓶了,然后我把V-1再去除以4,为什么呢?如果V-1除以4余数为2(只能为2或者0,因为都是2的次幂),就代表余下的升数中,我一定要买一瓶2L的,那么接下来再去看这个2L的能不能用1L的去替代呢?(我就去查找我最初计算的那个表),然后我继续,我用v -1-2,去除以8.。。。。。一直到最后余下的容量一定是2的次幂,然后就再去把这个容量根据刚才计算的数组去找到最优的值。
这个算法,我不知道是否为最优值,但是其是一个很典型的贪心算法,有人感兴趣的话可以验证一下,如果不是最优的,请告知。

编程之美1.6 饮料供货[动态规划vs贪心算法] 饮料供货是一个求最优解问题。需要在给定最大容量V的前提下,从不同容量不同满意度的饮料中选择满意度最大的集合。 1. 动态规划: 动态规划是最常用的解决最优化问题的方法,很容易应用到本题的需求中。用f[V,i]表示从第i,i+1,i+2,...,n-1种饮料中,算出总量为V的方案中满意度之和的最大值。 动态规划方程为:f[V,i] = max{k*Hi + f[V-k*Vi, i+1]} 弄 阅读详情

相关推荐

Globus 数据下载

Globus 大数据下载流程~

weixin_43978558的博客 6616

编程之美——饮料供货

题目:在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。 管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙

cjc211322的专栏 1943

Springboot信息泄露以及heapdump的利用

努力是为了不平庸~安全有些时候是枯燥的,这一次,让我们先人一步,趣学渗透!

LiBai'S BLOG 3万+

编程之美(六)饮料供货

在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?NoNoNo,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。 管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙多时...

小二笙的博客 536

IATF16949核心职位全解析

TM / Top MgmtMR / QMRProcess OwnerQMQAQCSQECQEPQEPETEMEIEPM / PJMFMEA ModeratorMSA CoordinatorSPC CoordinatorCM / CCB内审员CP / CPK

weixin_49938552的博客 972

redhawk-sc(seascape)学习日志2

design view是主view,是所有seascape view中最root的部分,一个design view可以驱动多种类型分析比如静态IR drop,动态IR drop以及EM.这些分析可以在不同的PVT和翻转率下.Design view是一个必须的view对于redhawk中的任何类型分析来说。seascape view相当于一个容器,用于保存各种和设计相关的数据,类似于逻辑信息、物理信息等等,每个view都有其对应的输入件和依赖,这些view都是redhawk用于各种类型的分析所需。

qq_39493558的博客 3497

编程之美之饮料供货问题

对编程之美中饮料供货问题的解法

七贤的优快云 1147

LAMMPS实战指南 - 从in文件到分子动力学模拟的完整流程解析

本文详细解析了LAMMPS分子动力学模拟的完整流程,从理解in文件的核心作用与基础结构开始,逐步指导如何创建模拟体系、选择势函数、进行能量最小化与初始化,并深入讲解了NVT/NPT系综弛豫与生产模拟的关键步骤。文章还提供了常见问题的避坑指南与实战技巧,帮助初学者快速掌握从编写in文件到成功运行模拟的全过程。

weixin_28365523的博客 393

编程之美:饮料供货

题目大意: 水房能容纳饮料的总量是V,有一批饮料,每种饮料单个容量都是2的方幂,每种饮料信息如下:(Si,Vi,Ci,Hi)分别对应(名字,容量,满意度),求在满足总容量等于V的情况下,求满意度的最大值。 分析: 1、动态规划解法,不难看出这是一道完全背包问题 具体思路解法见:第七章 背包问题——完全背包 2、动态规划法的变形:备忘录法 #include #include usin

王川的私房菜 2181

Halcon实战:5分钟搞定金属表面划痕检测(附完整代码解析)

本文提供了一份基于Halcon的金属表面划痕检测实战指南。通过核心的动态阈值算法,快速从图像中提取局部对比度异常区域,并结合形态学后处理与特征筛选,精准识别划痕。文章详解了从代码搭建、参数优化到工业场景适配的全流程,帮助工程师在五分钟内构建稳定高效的机器视觉检测方案。

weixin_29084231的博客 495

计算机实战分享3:森林火灾预测分析可视化机器学习预测-完整数据代码-可直接运行

计算机实战分享3:森林火灾预测分析可视化机器学习预测-完整数据代码-可直接运行

604

饮料供货问题

题目:在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。 管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙

一首简单的歌 822

MFC Windows 程序设计[122]之树形下拉列表框(附源码)

MFC是微软公司提供的一个类库(class libraries),用以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。有很多初学MFC的小伙伴们都觉得MFC比较难学,看书吧,看了就忘了,网上的一些教程又是写的含糊不清,故而学习起来很吃力...... 故此,本专栏亲自研究,实践,由易到难,层层深入,将调试过程中所遭所遇进行详细讲解,注意事项进行一一列举,希望能够帮助到各位初学MFC的小伙伴,避免走弯路,费时费力。.........

hnjzfwy的博客 458

第1章 游戏之乐——饮料供货

饮料供货 1. 问题描述 在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。 管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、...

weixin_30237281的博客 138

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

编程之美-饮料供货-动态规划

[code="java"] import java.util.Arrays; import java.util.Random; public class BeverageSupply { /** * 编程之美 饮料供货 * 设Opt(V’,i)表示从i到n-1种饮料中,总容量为V’的方案中,满意度之和的最大值。 * 那么递归式就应该是:Opt(V’,i)=m...

代码说-Let code talk 264

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

编程之美之饮料供货

在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。 管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙多时,阿姨

fangjian1204的专栏 1463

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

1.6饮料供货

【代码】1.6饮料供货。

2401_89287074的博客 124

编程之美 - 饮料供货

在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙多时,阿姨

phphot 2985

答案_饮料供货

BOPGroup的专栏 2031

编程之美 - 1.6 饮料供货 ☞ 【记忆化搜索】

上接:编程之美 - 1.6 饮料供货 ☞ 【动态规划】 package Chapter1; import java.io.*; public class Func_1_6_2 { Beverage []beverages = null; int [][]opt = null; public static void main(String []args) {

PeersLee的博客 619

[编程之美]饮料供货

动态规划解之 http://www.cnblogs.com/daniagger/archive/2012/03/19/2406235.html View Code 1 /* 2 总共n中饮料,每种饮料表示为(S[i],V[i],C[i],H[i],B[i]),S表示名称,V表示容量,C表示可能的最大容量,H表示满意度,B表示实际购买量 3 V[i]*B[i]求和=V的

happylife1527的专栏 1091
上一篇: 快速找出故障机器
下一篇: 光影切割问题
云金
博客等级 码龄11年 11粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值