饮料供货
书中开始又是一堆看不懂的前述,感觉说了半天也没说清楚题目,看了解法一才看明白。
题目:假设STC共提供n中饮料,用(Si ,Vi,Ci,Hi,Bi )(对应的是饮料的名字,容量,可能的最大数量,满意度,实际购买量)来表示第i种饮料(i=0,1,…,n-1),其中可能的最大数量是指STC存货的上限。
基于如上表示:
饮料总容量为:
总满意度为:
那么题目要求就是,在满足条件∑_(i=0)(n-1)▒〖(V_i*B_i)〗=V的基础上求解max∑_(i=0)(n-1)▒〖(H_i*B_i)〗。
解题思路:
1. 动态规划
用Opt(V’,i)表示从第i,i+1,…n种饮料中,算出总量为V’的方案中满意度之和的最大值。
因此,Opt(V,1)中饮料就是我们要求值。
动态规划中心思想就是把大问题化解为小问题,先考虑当前的问题,即有
最优结果 = 选择k个第i种饮料的满意度 + 剩下的部分不考虑第i种饮料的最优结果
推导公式就是:
初始边界条件:
Opt(0,n)=0,即容量为0的情况下,最优化结果为0。
Opt(x,n)=-INF(负无穷)
2. 简单想法
在最大限制下购买最大单位满意度的饮料就行了,限制就是总容量和饮料的最大可能数量。
示例代码:
#include <iostream>
#include <iostream>
#define MAXV 100
#define MAXT 20
#define INF 0x7fffffff
#define N 7
using namespace std;
int v[N] = { 2,4,8,2,4,8,16 };
int c[N] = { 3,2,1,3,2,4,1 };
int h[N] = { 20,30,25,30,15,30,100 };
int opt[MAXV + 1][MAXT + 1];
// 记录每种饮料购买数量
int opt_num[MAXV + 1][MAXT + 1];
// 每种饮料的容量
int VV[MAXT];
// 每种饮料的容量上限(购买上限)
int CC[MAXT];
// 每种饮料的满意度
int HH[MAXT];
// 每种饮料的实际购买量
int BB[MAXT];
int T;
int Cal1(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 <= CC[type]; i++)
{
int temp = Cal1(V - i*VV[type], type + 1);
if (temp != -INF)
{
temp += HH[type] * i;
if (temp > ret)
{
// 记录购买V升饮料,type类型的饮料的数量。
opt_num[V][type] = i;
ret = temp;
}
}
}
return opt[V][type] = ret;
}
int main()
{
// 饮料总数
int totle;
// 总共的购买量
T = N;
totle = 64;
for (int i = 0; i <= T - 1; i++)
{
VV[i] = v[i]; // 饮料的容量
CC[i] = c[i]; // 容量
HH[i] = h[i]; // 满意度
}
memset(opt, -1, sizeof(opt));
int r = Cal1(totle, 0);
// 下面输出每种饮料的实际供应量。
cout << "0:" << opt_num[totle][0] << endl;
// 第0种饮料的数量(单位:个)
int k = opt_num[totle][0];
// t是饮料总供应量(单位:升)
int mm = totle;
// 依次计算第1种到第T-1种饮料的实际供应量
for (int i = 1; i <= T; i++)
{
// mm-k*VV[i-1]是剩余饮料供应量(单位:升)
int temp = opt_num[mm - k*VV[i - 1]][i];
cout << i << ":" << temp << endl;
mm -= k*VV[i - 1];
// k保存当前饮料供应量
k = temp;
}
cout << "最大的满意度:";
cout << r << endl << endl;
system("pause");
return 0;
}
总结:还是动态规划,看来要暂时停止学习编程之美了,先去看看算法导论了。