栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

动态规划之背包问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动态规划之背包问题

无限背包

一个在旅途中的长者有一个最多能装M公斤的背包;

现在有n种物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn;

输入n、m以及各种物品的重量和价值,求旅行者能获得最大总价值。

输入:

3 16
5 4
4 3
6 6

输出:

12

代码与01背包几乎一样,只是枚举的顺序不同而已。

01背包枚举容量时,从大到小,避免一个物品被选择多次;

无限背包枚举容量时,从小到大,允许一件物品没做选择多次。

#include 
int n, m, i, j, k, w, v, f[105];
int main(){
    freopen("wxbag.in", "r", stdin);
    scanf("%d%d", &n, &m);
    for(i=1; i<=n; i++){
        scanf("%d%d", &w, &v);
        for(j=w; j<=m; j++){
            if(f[j-w] + v > f[j]){
                f[j] = f[j-w] + v;
            }
        }
    }
    printf("%dn", f[m]);
    return 0;
}

多重背包

一个在旅途中的长者有一个最多能装M公斤的背包;

现在有n种物品,它们的重量分别是W1,W2,...,Wn,价值分别为V1,V2,...,Vn,数量分别为C1,C2,...,Cn;

输入n、m以及各种物品的重量、价值和数量,求旅行者能获得最大总价值。

输入:

3 16
5 4 2
4 3 5
6 6 1

输出:

12

多重背包,是指一个物品,可以选择多次;解法可以是将一件物品拆成多件物品。

如一件物品可以选择5次,那么我们可以看成是有5件那样的物品,做5次01背包即可。

#include 
int n, m, i, j, k, w, v, c, f[105];
int main(){
    freopen("dcbag.in", "r", stdin);
    scanf("%d%d", &n, &m);
    for(i=1; i<=n; i++){
        scanf("%d%d%d", &w, &v, &c);
        while(c--){
            for(j=m; j>=w; j--){
                if(f[j-w] + v > f[j]){
                    f[j] = f[j-w] + v;
                }
            }
        }
    }
    printf("%dn", f[m]);
    return 0;
}

混合背包

有的物品只能选1次,有的物品可以选择多次,有的物品可以选择很多次……混合在一起,就是混合背包。

如多重背包中,物品的数量c很大,那就好超时了;数量很大时,应转成无限背包去做。

#include 
int n, m, i, j, k, w, v, c, f[105];
int main(){
    freopen("dcbag.in", "r", stdin);
    scanf("%d%d", &n, &m);
    for(i=1; i<=n; i++){
        scanf("%d%d%d", &w, &v, &c);
        if(c*w >= m){
            for(j=w; j<=m; j++){
                if(f[j-w] + v > f[j]){
                    f[j] = f[j-w] + v;
                }
            }
        }
        else{
            while(c--){
                for(j=m; j>=w; j--){
                    if(f[j-w] + v > f[j]){
                        f[j] = f[j-w] + v;
                    }
                }
            }
        }
    }
    printf("%dn", f[m]);
    return 0;
}

练习题 1 -- [C++一本通-动态规划]例9.12 完全背包 题目描述

设有n 种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为m,今从n 种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于m,而价值的和为最大。

输入

第1行:两个整数,m(背包容量,m<=200)和n(物品数量,n<=30);

第2至n+1行:每行两个整数Wi,Ci,表示每个物品的重量和价值。

输出

仅一行,一个数,表示最大总价值。

样例输入
10 4
2 1
3 3
4 5
7 9
样例输出
max=12
参考代码
#include
using namespace std;
const int qwq = 3000;
int m,n;
int w[qwq],v[qwq];
int dp[qwq][qwq];
int main() {
	cin>>m>>n;
	for(int i = 1; i <= n; i++) {
		cin>>w[i]>>v[i];
	}
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			if(j < w[i]) {
				dp[i][j] = dp[i-1][j];
			} else {
				if(dp[i - 1][j] > dp[i][j - w[i]] + v[i]) {
					dp[i][j] = dp[i - 1][j];
				} else {
					dp[i][j] = dp[i][j - w[i]] + v[i];
				}
			}
		}
	}
	cout<<"max="< 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/717893.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号