前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Backpack problem

Backpack problem

作者头像
AngelNH
发布2020-04-16 15:39:05
3720
发布2020-04-16 15:39:05
举报
文章被收录于专栏:AngelNI

1、01背包

代码语言:javascript
复制
/*
一共有n件物品,背包容量为m,每件物品有体积weight 和value,求背包可以装的最大价值。

01背包是最简单的背包问题,每件物品只有选与不选两种情况:

dp[i][j] :表示选第i件物品时重量为j的最大价值。
1.不选第i件物品
dp[i][j] = dp[i-1][j]
2.选第i件物品的最大值(背包容量足够)
dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i])

*/
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 1010;
int dp[N][N],weight[N],value[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i =1;i<=n;++i)
    {
        cin>>weight[i]>>value[i];
    }
    for(int i =1;i<=n;++i)
    {
        for(int j =0;j<=m;++j)
        {
            dp[i][j] = dp[i-1][j];
            if(j>=weight[i])
            {
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i]);
            }
        }
    }
    /*
    一维优化
    int dp[N];
    for(int i=1;i<=n;++i)
    {
    	for(int j =m;j>=weight[i];--j)
    	{
    		dp[j] = max(dp[j],dp[j-weight[i]] + value[i]);
    	}
    }
    ans = dp[m];
    */
    int ans = dp[n][m];
    cout<<ans<<endl;
    system("pause");
    return 0;
}
// 练习1 HDU2602 HDU2546,HDU2955,HDU1203,HDU1171,HDU2639,
// 练习2 https://www.acwing.com/problem/content/2/

2、完全背包

代码语言:javascript
复制
/*
完全背包与01背包的区别是每件物品有无限个,每件物品可以去N件;
for(int i =1;i<=n;++i)
{
	for(int j =m;j>=weight[i];--j)
	{
        for(int k =0;k*weight[i]<=j;++k)
        {
            dp[j] = max(dp[j],dp[j-k*weight[i]]+k*value[i]);
        }
	}
}
优化之后变为:
for(int i =1;i<=n;++i)
{
	for(int j =weight[i];j<=m;++j)
	{
		dp[j] = max(dp[j],dp[j-weight[i]] + value[i]);
		
	}
}
*/
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 1010;
int dp[N],weight[N],value[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i =1;i<=n;++i)
    {
        cin>>weight[i]>>value[i];
    }
    for(int i =1;i<=n;++i)
    {
        for(int j =weight[i];j<=m;++m)
        {
            dp[j] = max(dp[j],dp[j-weight[i]]+value[i]);
        }
    }
    int ans = dp[m];
    cout<<ans<<endl;
    return 0;
}
//练习https://www.acwing.com/problem/content/3/
//

3、多重背包

代码语言:javascript
复制
/*
多重背包与上述背包的区别是,每件物品只有有限个,拿取的数量有限。
*/
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 110;
int n,m;
int dp[N];
int w[N],v[N],s[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;++i)
    {
        cin>>w[i]>>v[i]>>s[i];
    }
    for(int i=1;i<=n;++i)
    {
        for(int j = m ;j>=0;--j)
        {
            for(int k= 1;k<=s[i]&&k*w[i]<=j;++k)
            {
                dp[j] = max(dp[j],dp[j-k*w[i]]+ k*v[i] ) ;
            }
        }
    }
    int ans = dp[m];
    cout<<ans<<endl;
    system("pause");
    return 0;
}
// 练习 https://www.acwing.com/problem/content/4/
代码语言:javascript
复制
//二进制优化
/*
多重背包与上述背包的区别是,每件物品只有有限个,拿取的数量有限。
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;
const int N = 2200;
int n,m;
int dp[N];
int w[N],v[N],s[N];
struct good
{
    int w,v;
};
int main()
{
    cin>>n>>m;
    vector<good> goods;
    for(int i=1;i<=n;++i)
    {
        int w,v,s;
        cin>>w>>v>>s;
        for(int k=1;k<=s;k*=2)
        {
            s-=k;
            goods.push_back({w*k,v*k});
        }
        if(s>0) goods.push_back({w*s,v*s});
    }
    for(auto it = goods.begin();it!=goods.end();++it)
    {
        for(int j = m ;j>=it->w;--j)
        {
            
                dp[j] = max(dp[j],dp[j-it->w]+ it->v ) ;
            
        }
    }
    int ans = dp[m];
    cout<<ans<<endl;
    system("pause");
    return 0;
}
// 练习 https://www.acwing.com/problem/content/4/

4、混合背包

代码语言:javascript
复制
/*
混合背包是每件物品分为三类:
1.只有拿与不拿两种状态
2.有无数件
3.件数有限制
混合背包问题分组解决子问题
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

const int N = 1010;

struct Thing
{
    int kind;
    int w,v;
} ;
int dp[N];
int main()
{
    vector<Thing > thing;
    int n,m;
    cin>>n>>m;
    for(int i =1;i<=n;++i)
    {
        int v,w,s;
        cin>>w>>v>>s;
        if(s<0)
            thing.push_back({-1,w,v});
        else if(s==0) 
            thing.push_back({0,w,v});
        else
        {
            for(int k=1;k<=s;k*=2)
            {
                s-=k;
                thing.push_back({-1,w*k,v*k});
            }
            if(s>0)
                thing.push_back({-1,s*w,s*v});
        }
    }
    for(auto it = thing.begin();it!=thing.end();++it)
    {
        if(it->kind < 0)
        {
            for(int j=m;j>=it->w;j--)
            {
                dp[j] = max(dp[j],dp[j-it->w]+it->v);
            }
        }
        else
        {
            for(int j =it->w;j<=m;++j)
            {
                dp[j] = max(dp[j],dp[j-it->w]+it->v);
            }
        }
        
    }

    
    cout<<dp[m]<<endl;
    system("pause");
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-02-12|,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、01背包
  • 2、完全背包
  • 3、多重背包
  • 4、混合背包
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档