甜品店切蛋糕问题(动态规划,Go语言实现)
来源:互联网 发布:c语言字符串指针 编辑:程序博客网 时间:2024/04/28 05:46
甜品店切蛋糕问题(动态规划,Go语言实现)
问题重现:
小Y最近在甜品店工作,其工作是切蛋糕。现在有n个顾客来购买蛋糕,并且每个顾客有一个到达的时间,以及需要买的蛋糕的长度ai。由于小Y每次只能服务一个顾客,【问题严谨性补充:而顾客如果进店没有服务员立刻为他服务,他将离开】所以对于相冲突的顾客没有办法提供服务。问小Y最多能为多少位顾客提供服务。小Y能够决定是否卖蛋糕给某个顾客。如果答应顾客要买长度为ai的切糕,那么小Y还要将蛋糕切成单位长度给顾客。如果对ai的蛋糕切成x和ai-x,所花的时间代价为x*(ai-x)。例如,当一个用户在1时刻,需要长度为4的蛋糕,此时小Y可以将其先切成2分长度为2的,花费为4,再将两段长度为2的分别切成1,1的,花费分别为1和1,则总花费时间为4+1+1 = 6, 则小Y为该用户服务时间为6.
已知第i位顾客进店时间,以及购买蛋糕大小。【作者特别说明:在原题上稍有修改,本文重在讲清思想】
分析:(转载请注明出处和作者名)
涉及问题一:大小为n的蛋糕需要多长时间切成单位长度?
f(x)=x*(n-x) 绘制函数草图可以得到:x=1时得到最小值,也就是说每次1单位1单位的切
用数学归纳法证明上述的解得到的最终和解也是最小的
n=2时 f(x)显然得到的最小解
n=3时 f(x)显然得到的最小解
n=4时 f(x)显然得到的最小解
...
假设n=i-1时也能得到最小解
n=i时
切成x 和(i-x)
显然x必然是前面已经推出的n的一个解,i-x也是前面推出的一个解,而f(x)的最优解和f(i-x)就是每次1单位1单位的切
这时只要保证x*(i-x)值最小即可,最小情况x=1,也就证明了每次1单位1单位的切的解得到的最终和解也是最小的。
涉及问题二:已知各位顾客的进店时间和购买蛋糕大小,如何选出最佳服务对象?
这个问题至少可以使用贪心策略来解决,似乎包含了动态规划,看起来很像01背包问题
动态规划:
f[i][t]表示t时间内在前i个人已服务完的服务对象人数
s[i]表示第i个人需要的服务时长
r[i]表示第i个人达到时间点
㈠对于是否选择服务第i个人有两种情形
①选择,但要满足完成第i人的服务后时间不超过t
(如果选择了第i个人,可能就存在不允许选前i-1个人中的某些人)
f[i][t]=f[i-1][r[i]]+1 【t>=r[i]+s[i]】
②不选,不改变在t时间的策略
(之所以不选的原因,就是因为第i个人到时,小Y还没有为前面的人服务完,又或者如果选了第i人会耽误后面更多的人)
f[i][t]=f[i-1][t]
㈡决策退出条件(决策既知条件)
时间没有负数,所以无需判断
i==0 返回1或0
解释:因为i==0即最后一个人,如果满足条件t >= r[0]+s[0],返回1
㈢决策入口条件
t=max{s[i]+r[i]}
于是可以得出:
状态转移方程为:f[i][t]=max{ f[i-1][t-s[i]] (t>=r[i]+s[i]),
f[i-1][t]}
以下给出Go语言实现代码:
package mainimport ("fmt")/*求最小服务时长,每次1单位1单位的切,得到的是最小解*/func smin(n int32) int32 {if n&1 == 0 {return (n / 2) * (n - 1)}return (n - 1) / 2 * n}/*求每个顾客的时间*/func serverTime(s, lenght []int32, maxLen int32) {for i := range lenght {s[i] = smin(lenght[i])}}/*求二者最大值*/func maxInt32(a, b int32) int32 {if a > b {return a}return b}/*DP问题核心 作者:天之 CSDN博客:http://blog.csdn.net/WAPWO?viewmode=contents*/func dptz(i, t int32, r, s []int32) int32 {if i == 0 {if t >= r[0]+s[0] {return 1}return 0}if t >= r[i]+s[i] {return maxInt32(dptz(i-1, r[i], r, s)+1, dptz(i-1, t, r, s))}return dptz(i-1, t, r, s)}/*求最后结束时间*/func endTime(r, s []int32) int32 {var max, tmp int32 = 0, 0for i := range r {tmp = r[i] + s[i]if max < tmp {max = tmp}}return max}func main() {//蛋糕长度、先来后到的时间和服务时间length := []int32{2, 2, 3, 4}r := []int32{5, 5, 6, 10}s := make([]int32, 4)serverTime(s, length, 4)fmt.Println(dptz(3, endTime(r, s), r, s))}
- 甜品店切蛋糕问题(动态规划,Go语言实现)
- 甜品店切蛋糕问题(动态规划,Go语言实现)
- 动态规划——切蛋糕
- 0-1背包问题(动态规划C语言实现)
- 动态规划之分蛋糕
- Go语言动态规划矩阵连乘
- C语言实现之三角形问题(非动态规划方法)
- 01背包问题 动态规划 c语言实现
- 利用动态规划法求解旅行商问题(TSP)的C语言实现(一)
- TSP问题 动态规划实现
- 切蛋糕问题
- 切蛋糕问题
- C语言最大子段和问题(动态规划)
- 动态规划之背包问题(C语言)
- C语言实现 poj3666(动态规划)
- 魔术师发牌问题GO语言实现
- TSP问题的动态规划解法(c#实现)
- LCS问题实现---------------(动态规划, 取自算法导论)
- 用这些东西可以用Lua实现画面菜单保持可选同时连接socket
- listview 去除每行的分割线
- magento各版本简称及翻译
- 转换操作符的使用
- lldb的alias别名功能
- 甜品店切蛋糕问题(动态规划,Go语言实现)
- 关于phprpc for java搭建android服务端
- Android Intent Filter简单使用
- 指向结构变量的指针
- 获取ip以及地理位置
- linux下configure命令详细介绍
- ipcs
- Ubuntu下安装pip
- 无鸯 Android中自定义属性(attrs.xml,TypedArray)的使用,