编程之美1.6 饮料供货

问题描述:      在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件? No, 是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙多时,阿姨们逮住了他,要他帮忙。      从阿姨们统计的数据中,小飞可以知道大家对每一种饮料的满意度。阿姨们还告诉小飞, STC( Smart   Tea   Corp.) 负责给研究院供应饮料,每天总量为 V。 STC 很神奇,他们提供的每种饮料之单个容量都是 2 的方幂,比如王老吉,都是 23 = 8 升的,可乐都是 25 = 32 升的。当然 STC 的存货也是有限的,这会是每种饮料购买量的上限。统计数据中用饮料名字、容量、数量、满意度描述每一种饮料。那么,小飞如何完成这个任务,求出保证最大满意度的购买量呢?

问题分析:      现有的条件包括 1. 总量V 2. 每种饮料的单个容量 3. 每种饮料的存货

     这个问题适合使用动态规划来寻找最优解。首先方便讨论我们按照书中的命名设好一些变量:

     “假设STC共提供n种饮料,用(Si、Vi、Ci、Hi、Bi)(对应的是饮料名字、容量、可能的最大数量、满意度、实际购买量)来表示第i种饮料(i = 0, 1,…, n-1),其中可能的最大数量指如果仅买某种饮料的最大可能数量,比如对于第i中饮料Ci=V/Vi。”

     动态规划的步骤包括:1.分析最优解结构特点;2.递归定义最优解;3.自底向上计算子问题直至得到最优解的代价;4.找到最优解。那么我们接下来就按照这个步骤顺序依次来进行分析。      首先是最优解结构。最优解设为是B1,B2,B3…Bn,那么B1到Bn-1是这样的一个子问题的最优解:总量V-Bn*Vn,在前n-1种饮料中选出满意度最大的方案。这个很好证明,因为假如这不是子问题的优化解,那么原问题就可以得到一个更好的解,矛盾。接下来需要分析的就是这个子问题的解和它的父问题(可以这么叫吗)的最优解之间的关系,列出递推方程。假如当前购买的饮料后剩余的量为k,那么需要比较k和Vn之间的关系。假如不能整除,那么显然这样的方案是不成立的,需要舍弃,可以给这个方案的满意度设为无穷小,假如可以整除,那么就需要开始进行判断。

     具体而言,我们可以设一个代价函数c[i,j]表示当前状态的满意度,其中i表示从前i种饮料中选择,j表示当前剩余的饮料量。当i=n,j=v的时候,我们就得到了原问题的最优满意度。如何从c[i,j]的下一级子问题得到它的值呢,这个需要进行比较,设第i种饮料的购买量为m,然后考察对于每一种m的可能情况下得到的值,选出最大的填入c[i,j]。当填完整个表后就得到了整体的最优解。

    原文作者:jarelzhou
    原文地址: https://blog.csdn.net/jarelzhou/article/details/19203995
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞