编程之美之 饮料供货 之 动态规划算法和备忘录算法实现

    //
     
    #include "stdafx.h"
    #include <cstdlib>
    #include <string>
    #include <iostream>
    //#include <string.h>
    #define V 64// total volume 不一定恰好能放得下,可能有剩余的空间什么也放不了
    #define N 7// the number of the beverage
    using namespace std;
     
    int opt[V+2][N+2];//第一行全零,最后一列是-1000;
    //int v[N+1]={0,2,4,2};
    //int c[N+1]={0,3,2,1};
    //int h[N+1]={0,20,30,25};
    int v[N+1]={0,2,4,8,2,4,8,16};
    int c[N+1]={0,3,2,1,3,2,4,1};
    int h[N+1]={0,20,30,25,30,15,30,100};
    int b[V+1][N+1]={0};
    int b2[V+1][N+1]={0};
     
    int cal(int vi,int i)// cal(V,1)
    {
        if(i==N+1)
        {
            if(vi==0)return 0;
            else return -1000;
        }
        if(vi<0) return -1000;
        if(vi==0) return 0;
        else
            if(opt[vi][i]!=-1) return opt[vi][i];
        int ret=-1000;
        int k;
        for(k=0;k<=c[i];k++)
        {
            //if(vi<k*v[i])break;
            int temp=cal(vi-k*v[i],i+1);
            if(temp!=-1000)
            {
                temp+=k*h[i];
                if(temp>ret)
                {
                    ret=temp;    
                    b2[vi][i]=k;
                }
            }
        }
        opt[vi][i]=ret;
        return ret;
    }
     
    void memo_fun()
    {
        for(int i=0;i<=V+1;i++)
        for(int j=0;j<=N+1;j++)
            opt[i][j]=-1;//特殊标记
        int cc=cal(V,1);
     
        /*for(int i=0;i<=V+1;i++)
        {
            for(int j=0;j<=N+1;j++)
            cout<<opt[i][j]<<" ";
            cout<<endl;
        }
            for(int i=0;i<=V+1;i++)
        {
            for(int j=0;j<=N+1;j++)
            cout<<b2[i][j]<<" ";
            cout<<endl;
        }*/
        cout<<"bigest happiness is "<<cc<<endl;
        int buy[N];
        int m,test;
        for(int j=1,m=V;j<=N;j++)//最后一列只有一个不为零的
        {
            if((b2[m][j]!=0)&&(opt[m][j]!=-1000))
                buy[j-1]=b2[m][j];
            else buy[j-1]=0;
     
            test=opt[m][j]-b2[m][j]*h[j];
            //cout<<"test is"<<b[m][j]<<" "<<test<<endl;
            for(int i=V;i>=1;i--)
            if(test==opt[i][j+1]) m=i;
            
        }
        cout<<"real buy is "<<endl;
        for(int i=0;i<N;i++)
        {
            cout<<buy[i]<<" ";    
        }
        cout<<endl;
    }
    void dynmic_fun()
    {
        opt[0][N+1]=0;
        for(int i=0;i<=N+1;i++)
        opt[0][i]=0;
        for(int i=1;i<=V+1;i++)
        opt[i][N+1]=-1000;//why set -1000 ?
        for(int j=N;j>=0;j--)
        {
            for(int i=1;i<=V;i++)
            //for(int j=1;j<=N;j++)
            {
                opt[i][j]=-1000;//why set -1000 ?
                for(int k=0;k<=c[j];k++)
                {
                    if(i<k*v[j])break;
                    int temp=opt[i-k*v[j]][j+1];
                    if(temp!=-1000)
                    {
                        
                        temp+=k*h[j];
                        if(temp>opt[i][j])
                        {
                            opt[i][j]=temp;
                            b[i][j]=k;
                        }
                    }
                }
            }
        }
        /*for(int i=0;i<=V;i++)
        {
            for(int j=0;j<=N;j++)
            cout<<opt[i][j]<<" ";
            cout<<endl;
        }
        for(int i=0;i<=V;i++)
        {
            for(int j=0;j<=N;j++)
            cout<<b[i][j]<<" ";
            cout<<endl;
        }*/
        cout<<endl<<"bigest happiness is"<<opt[V][1]<<endl;
        int buy[N];
        int m,test;
        for(int j=1,m=V;j<=N;j++)//最后一列只有一个不为零的
        {
            if((b[m][j]!=0)&&(opt[m][j]!=-1000))
                buy[j-1]=b[m][j];
            else buy[j-1]=0;
            test=opt[m][j]-b[m][j]*h[j];
            //cout<<"test is"<<b[m][j]<<" "<<test<<endl;
            for(int i=V;i>=1;i--)
            if(test==opt[i][j+1]) m=i;
            
        }
        cout<<"real buy is "<<endl;
        for(int i=0;i<N;i++)
        {
            cout<<buy[i]<<" ";    
        }
        cout<<endl;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        //? int opt[V+2][N+2];//第一行全零,最后一列是-1000;
        //int v[N+1]={0,2,4,8,2,4};
        //int c[N+1]={0,3,2,1,3,2};
        //int h[N+1]={0,20,30,25,30,15};
     
        //int b[V+1][N+1]={0};
        cout<<"动态规划算法实现"<<endl;
        dynmic_fun();
        //system("pause");
        cout<<"备忘录算法实现"<<endl;
         memo_fun();
     
        system("pause");
        return 0;
    }
---------------------
作者:littlestream9527
来源:CSDN
原文:https://blog.csdn.net/littlestream9527/article/details/7989573
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-07-19 12:59  天涯海角路  阅读(162)  评论(0)    收藏  举报