0/1背包,完全背包,多重背包 问题 C++实现

参考博客 https://blog.csdn.net/na_beginning/article/details/62884939

 

/***************************************************
*  函数功能:0/1 背包问题 递归和非递归版本
*  参数说明
*       输入参数: weight  = { 3, 2, 4, 7 };
                   costs   =  { 5, 6, 3, 19 };
                   max_bag = 11;
*       输出参数: 25
*  复杂性分析:时间复杂度:O(N*M),空间复杂度:O(N*M)
*  题目来源  :
*  作者:guoliang zheng
*  日期:2018-08-15-10.19
***************************************************/
int Bag_Quistion::get_MAX_value(vector<int> weight,vector<int> costs,int max_bag)
{
    if(weight.size()<1 || costs.size()<1 || max_bag<1) return 0;
    int row=weight.size();
    vector<vector<int> > dp(row+1,vector<int>(max_bag+1,0));
    for(int i=row-1;i>=0;i--)
    {
        for(int j=0;j<=max_bag;j++)
        {
            dp[i][j]=dp[i+1][j];
            if(j-weight[i]>=0)
            {
                dp[i][j]=max(dp[i][j],costs[i]+dp[i+1][j-weight[i]]);
            }
        }
    }
    cout<<"--------------------------------"<<endl;
    for(int i=0;i<row;i++)
    {
        for(int j=0;j<=max_bag;j++)
        {
            printf("%3d ",dp[i][j]);
        }
        printf("\n");
    }
    vector<int> res(row,0);
    int r=0;
    int c=max_bag;
    while(r<row)
    {
        if(dp[r][c]==(dp[r+1][c-weight[r]]+costs[r]))
        {
            res[r]=1;
            c=c-weight[r];
        }
        r++;
    }
    for(int i=0;i<row;i++)
    {
        printf("%3d ",res[i]);
    }

    printf("\n");
    return dp[0][max_bag];
}

int Bag_Quistion::get_MAX_value_DG(vector<int> weight,vector<int> costs,int max_bag)
{
    if(weight.size()<1 || costs.size()<1 || max_bag<1) return 0;
    return get_MAX_value_DG(weight,costs,max_bag,0,0);
}

int Bag_Quistion::get_MAX_value_DG(vector<int> weight,vector<int> costs,int max_bag,int i,int allget)
{
    if(i==weight.size())
    {
        return 0;
    }
    if(allget>max_bag)
    {
        return 0;
    }
    int left=get_MAX_value_DG(weight,costs,max_bag,i+1,allget);
    int right=0;
    if(allget+weight[i]<=max_bag)
    {
        right=costs[i]+get_MAX_value_DG(weight,costs,max_bag,i+1,allget+weight[i]);
    }
    return max(left,right);

}

/***************************************************
*  函数功能:完全背包问题
*  参数说明
*       输入参数:
*       输出参数:
*  复杂性分析:时间复杂度:O(N*M),空间复杂度:O(N*M)
*  题目来源  :
*  作者:guoliang zheng
*  日期:2018-08-15-16.24
***************************************************/
int Bag_Quistion::get_MAX_value_Complete(vector<int> weight,vector<int> costs,int max_bag)
{
    if(weight.size()<1 || costs.size()<1 || max_bag<1) return 0;
    int row=weight.size();
    vector<vector<int> > dp(row+1,vector<int>(max_bag+1,0));
    for(int i=row-1;i>=0;i--)
    {
        for(int j=0;j<=max_bag;j++)
        {
            dp[i][j]=dp[i+1][j];
            if(j-weight[i]>=0)
            {
                dp[i][j]=max(dp[i][j],dp[i][j-weight[i]]+costs[i]);
            }
        }
    }

    for(int i=0;i<row;i++)
    {
        for(int j=0;j<=max_bag;j++)
        {
            printf("%3d ",dp[i][j]);
        }
        printf("\n");
    }
    vector<int> res(row,0);
    int r=0;
    int c=max_bag;
    while(r<row)
    {
        while(dp[r][c]==dp[r][c-weight[r]]+costs[r])
        {
            res[r]++;
            c=c-weight[r];
        }
        r++;
    }
    for(int i=0;i<row;i++)
    {
        printf("%3d ",res[i]);
    }
    printf("\n");
    return dp[0][max_bag];

}

/***************************************************
*  函数功能:多重背包问题
*  参数说明
*       输入参数:
*       输出参数:
*  复杂性分析:时间复杂度:O(N*M),空间复杂度:O(N*M)
*  题目来源  :
*  作者:guoliang zheng
*  日期:2018-08-15-16.24
***************************************************/
int Bag_Quistion::get_MAX_value_Limitnum(vector<int> weight,vector<int> costs,vector<int> number,int max_bag)
{
    if(weight.size()<1 || costs.size()<1 || number.size()<1 || max_bag<1 || weight.size()!=costs.size() || weight.size()!=number.size() || costs.size()!=number.size())
        return 0;
    int row=weight.size();
    vector<vector<int> > dp(row+1,vector<int>(max_bag+1,0));
    for(int i=row-1;i>=0;i--)
    {
        for(int j=0;j<=max_bag;j++)
        {
            dp[i][j]=dp[i+1][j];
            if(j-weight[i]>=0)
            {
                int counts=min(number[i],j/weight[i]);
                for(int k=1;k<=counts;k++)
                {
                    dp[i][j]=max(dp[i][j],dp[i+1][j-weight[i]*k]+k*costs[i]);
                }
            }
        }
    }
    for(int i=0;i<row;i++)
    {
        for(int j=0;j<=max_bag;j++)
        {
            printf("%3d ",dp[i][j]);
        }
        printf("\n");
    }
    vector<int> res(row,0);
    int r=0;
    int c=max_bag;
    while(r<row)
    {
        int counts=min(number[r],c/weight[r]);
        for(int k=counts;k>0;k--)
        {
            if(dp[r][c]==(dp[r+1][c-weight[r]*k]+k*costs[r]))
            {
                res[r]=k;
                c=c-weight[r]*k;
                break;
            }
        }
        r++;
    }
    for(int i=0;i<row;i++)
    {
        printf("%3d ",res[i]);
    }
    printf("\n");
    return dp[0][max_bag];
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值