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