饮料供货@编程之美

来源:互联网 发布:java web高级编程下载 编辑:程序博客网 时间:2024/04/29 08:06
题目:求出保证最大满意度的购买量?(供货总量是确定的)
假设共提供n中饮料,用(Si,Vi,Ci,Hi,Bi)(对应的饮料的名字,容量,可能的最大数量,满意度,实际购买量)
可能的购买量是指存货的上限。
饮料总容量为:求和i从0–n-1(Vi*Bi)

总满意度为:求和i从0–n-1(Hi*Bi)

通过对题目的分析,可以采用的算法包括动态规划、搜索以及贪心算法。

1.动态规划

首先选择动态规划,动态规划的话,状态转移函数为:

f[i][v] = max(f[i-1][v-k*c[i]]) + k*w[i]; 0 <= k <= n[i]

其中,c[i]表示选择i的cost,n[i]表示i能够选择的数量,w[i]表示选择i所带来的收益。

算法的具体实现如下:

#include <iostream>#include <vector>using namespace std;/**vv每种饮料的容量*cc每种饮料最大的数量*hh每种饮料的满意度*T饮料种类*V购买饮料的数量和*/int dynamic(int vv[],int cc[],int hh[],int T,int V);int main (){    int vv[]={1,2,8,4,16};    int cc[] = {50,20,30,50,20};    int hh[]={3,4,2,5,2};    int T = 5;    int V = 100;    cout << dynamic(vv,cc,hh,T,V);}int dynamic(int vv[],int cc[],int hh[],int T,int V){    const int INF = 1<<32-1;    vector<vector<int> > dp(vector<vector<int> >(T+1,vector<int>(V+1,INF)));    dp[T][0] = 0;//初始条件,表示当容量为0的时候,能够带来的收益是0    for(int i = T-1;i >=0 ;i --)    {        for(int j = 0;j <= V;j ++)        {            for(int k = 0;k <= cc[i];k ++)            {                if(j < k*vv[i]) break;                int x = dp[i+1][j-k*vv[i]];                if(x != INF)                {                    x += k*hh[i];                    if(x > dp[i][j])                    {                        dp[i][j] = x;                    }                }            }        }    }    return dp[0][V];}


2 搜索

搜索的话,如果直接搜索,会产生很多不必要的计算过程,为了避免进行重复计算,采用备忘录,也就是一个表格,来保存计算的临时结果。

主要的思路为,如果要求d[0][v],那么就应该先求d[1][v-k*c[0]]的值,依次往后推,通过保留中间的计算过程,能够得到有效地值。

具体代码如下:

#include <iostream>#include <vector>using namespace std;/**vv每种饮料的容量*cc每种饮料最大的数量*hh每种饮料的满意度*T饮料种类*V购买饮料的数量和*/const int INF= 1<<32 -1;int mysearch(int vv[],int cc[],int hh[],int curt,int curv,int T,int V,vector<vector<int> > &vvc);int main (){    int vv[]={1,2,8,4,16};    int cc[] = {50,20,30,50,20};    int hh[]={3,4,2,5,2};    int T = 5;    int V = 100;    vector<vector<int>> vvc(T+1,vector<int>(V+1,-1));    cout << mysearch(vv,cc,hh,0,V,T,V,vvc);}int mysearch(int vv[],int cc[],int hh[],int curt,int curv,int T,int V,vector<vector<int> > &vvc){    if(curt == T)    {        if(curv == 0)        {            return 0;        }        else        {            return INF;        }    }    if(curv < 0)    {        return INF;    }    else if(curv == 0)    {        return 0;    }    else if(vvc[curt][curv] != -1) return vvc[curt][curv];    int ret = -1;    for (int i = 0;i <= cc[curt];i ++)    {        int tmp = mysearch(vv,cc,hh,curt+1,curv-i*vv[curt],T,V,vvc);        if(tmp != INF)        {            tmp += i*hh[curt];            if(tmp > ret)            {                ret = tmp;            }        }    }    return vvc[curt][curv] = ret;}

3.贪心算法

书上有提到贪心算法,但是感觉贪心算法比较复杂,这里就不写出来了。可以参考:

http://blog.csdn.net/lichaoyin/article/details/9983883

http://blog.csdn.net/woniu317/article/details/20209055#t4


0 0
原创粉丝点击