《编程之美》读书随笔之六:饮料供货
题目:在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶、王老吉、咖啡、可口可乐……(当然,还是有很多同事把拿饮料当做第二件事)。
管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度。一段时间后,阿姨们已经有了大批的数据。某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶、四瓶王老吉、三瓶鲜橙多时,阿姨们逮住了他,要他帮忙。
从阿姨们统计的数据中,小飞可以知道大家对每一种饮料的满意度。阿姨们还告诉小飞,STC(Smart Tea Corp.)负责给研究院供应饮料,每天总量为V。STC很神奇,他们提供的每种饮料之单个容量都是2的方幂,比如王老吉,都是23=8升的,可乐都是25=32升的。当然STC的存货也是有限的,这会是每种饮料购买量的上限。统计数据中用饮料名字、容量、数量、满意度描述每一种饮料。
那么,小飞如何完成这个任务,求出保证最大满意度的购买量呢?
分析:具体见《编程之美》,下面的程序也是根据书上的几个解法来实现的:
-
-
-
-
using namespace std;
-
-
-
-
int opt[V+1][N+1];
-
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 cal(int y,int i)
-
{
-
if(i==N)
-
{
-
if(V==0)
-
return 0;
-
else
-
return -10000;
-
}
-
if(V<0)
-
return -10000;
-
else if(V==0)
-
return 0;
-
else if(opt[V][i]!=-1)
-
return opt[V][i];
-
int ret=-1;
-
for(int t=0;t<=c[t];t++)
-
{
-
int temp=cal(V-t*v[t],t+1);
-
if(temp!=-10000)
-
{
-
temp+=h[t]*t;
-
if(temp>ret)
-
ret=temp;
-
}
-
}
-
opt[V][i]=ret;
-
return opt[V][i];
-
}
-
-
//备忘录法
-
void memo_fun()
-
{
-
for(int i=0;i<=V;i++)
-
{
-
for(int j=0;j<N;j++)
-
{
-
opt[i][j]=-1;
-
}
-
}
-
int cc=cal(V,1);
-
cout<<"biggest happiness is "<<cc<<endl;
-
}
-
-
//动态规划法
-
void dynamic_fun()
-
{
-
opt[0][N]=0;
-
for(int q=0;q<=N;q++)
-
opt[0][q]=0;
-
for(int i=1;i<=V;i++)
-
opt[i][N]=-10000;
-
for(int j=N;j>=0;j--)
-
{
-
for(int i=1;i<=V;i++)
-
{
-
opt[i][j]=-10000;
-
for(int k=0;k<c[j];k++)
-
{
-
if(i<k*v[j])
-
{
-
break;
-
}
-
int x=opt[i-k*v[j]][j+1];
-
if(x!=-10000)
-
{
-
x+=h[j]*k;
-
if(x>opt[i][j])
-
{
-
opt[i][j]=x;
-
}
-
}
-
}
-
}
-
}
-
cout<<"the biggest happiness is: "<<opt[V][0]<<endl;
-
}
-
-
int main()
-
{
-
cout<<"动态规划算法实现"<<endl;
-
dynamic_fun();
-
cout<<"备忘录算法实现"<<endl;
-
memo_fun();
-
system("pause");
-
return 0;
-
}

浙公网安备 33010602011771号