动态规划之背包问题(01背包,完全背包,多重背包)

01背包

问题描述

有N个物品,每个物品的重量为weight[i],每个物品的价值为value[i]。现在有一个背包,它所能容纳的重量为V,问:当你面对这么多有价值的物品时,你的背包所能带走的最大价值是多少?

关键思路

每个物品无非是装入背包或者不装入背包,那么就一个一个的物品陆续放入背包中。
通过for(int i = V; i >= 0; i--)逆序保证物品的装入或不装入。

程序实现

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
    int N;//物品个数 5
    int V;//背包容量 15
    cin >> N >> V;
    int weight[N + 1];// 5 4 7 2 6
    int value[N + 1];// 12 3 10 3 6
    weight[0] = value[0] = 0;
    int maxTotalValue[V + 1]; //maxTotalValue[i]:背包已装容量为i时,背包里所装物品的最大总价值
    memset(maxTotalValue, 0, sizeof(maxTotalValue));
    for(int i = 1; i <= N; i++)
        cin >> weight[i] >> value[i];
    for(int j = 1; j <= N; j++)
        for(int i = V; i >= 0; i--)
            {
                cout << "背包已装容量:" << i << endl;
                if(i >= weight[j])
                    {
                        if(maxTotalValue[i] >= value[j] + maxTotalValue[i - weight[j]])
                            //cout << "背包中未装入物品:" << j << endl;
                            ;
                        else
                            {
                                maxTotalValue[i] = maxTotalValue[i - weight[j]] + value[j];
                                cout << "背包中已装入物品:" << j << endl;
                            }
                    }
                else
                    //cout << "背包中未装入物品:" << j << endl;
                    ;


            }
    cout << "背包能装物品的最大总价值:" << maxTotalValue[V] << endl;
    return 0;
}

运行结果及分析

5 15
5 12
4 3
7 10
2 3
6 6
背包已装容量:15
背包中已装入物品:1
背包已装容量:14
背包中已装入物品:1
背包已装容量:13
背包中已装入物品:1
背包已装容量:12
背包中已装入物品:1
背包已装容量:11
背包中已装入物品:1
背包已装容量:10
背包中已装入物品:1
背包已装容量:9
背包中已装入物品:1
背包已装容量:8
背包中已装入物品:1
背包已装容量:7
背包中已装入物品:1
背包已装容量:6
背包中已装入物品:1
背包已装容量:5
背包中已装入物品:1
背包已装容量:4
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包中已装入物品:2
背包已装容量:14
背包中已装入物品:2
背包已装容量:13
背包中已装入物品:2
背包已装容量:12
背包中已装入物品:2
背包已装容量:11
背包中已装入物品:2
背包已装容量:10
背包中已装入物品:2
背包已装容量:9
背包中已装入物品:2
背包已装容量:8
背包已装容量:7
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包中已装入物品:2
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包中已装入物品:3
背包已装容量:14
背包中已装入物品:3
背包已装容量:13
背包中已装入物品:3
背包已装容量:12
背包中已装入物品:3
背包已装容量:11
背包已装容量:10
背包已装容量:9
背包已装容量:8
背包已装容量:7
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包中已装入物品:4
背包已装容量:14
背包中已装入物品:4
背包已装容量:13
背包已装容量:12
背包已装容量:11
背包中已装入物品:4
背包已装容量:10
背包已装容量:9
背包已装容量:8
背包中已装入物品:4
背包已装容量:7
背包中已装入物品:4
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包已装容量:3
背包中已装入物品:4
背包已装容量:2
背包中已装入物品:4
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包已装容量:14
背包已装容量:13
背包已装容量:12
背包已装容量:11
背包已装容量:10
背包已装容量:9
背包已装容量:8
背包已装容量:7
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包能装物品的最大总价值:25

《动态规划之背包问题(01背包,完全背包,多重背包)》

完全背包

问题描述

有N个物品,每种物品有无限个,每个物品的重量为weight[i],每个物品的价值为value[i]。现在有一个背包,它所能容纳的重量为V,问:当你面对这么多有价值的物品时,你的背包所能带走的最大价值是多少?

关键思路

通过for(int i = 0; i <= V; i++)顺序保证物品的装入次数不限。

程序实现

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
    int N;//物品个数 5
    int V;//背包容量 15
    cin >> N >> V;
    int weight[N + 1];// 5 4 7 2 6
    int value[N + 1];// 12 3 10 3 6
    weight[0] = value[0] = 0;
    int maxTotalValue[V + 1]; //maxTotalValue[i]:背包已装容量为i时,背包里所装物品的最大总价值
    memset(maxTotalValue, 0, sizeof(maxTotalValue));
    for(int i = 1; i <= N; i++)
        cin >> weight[i] >> value[i];
    for(int j = 1; j <= N; j++)
        for(int i = 0; i <= V; i++)
            {
                cout << "背包已装容量:" << i << endl;
                if(i >= weight[j])
                    {
                        if(maxTotalValue[i] >= value[j] + maxTotalValue[i - weight[j]])
                            //cout << "背包中未装入物品:" << j << endl;
                            ;
                        else
                            {
                                maxTotalValue[i] = maxTotalValue[i - weight[j]] + value[j];
                                cout << "背包中已装入物品:" << j << endl;
                            }
                    }
                else
                    //cout << "背包中未装入物品:" << j << endl;
                    ;
            }
    cout << "背包能装物品的最大总价值:" << maxTotalValue[V] << endl;
    return 0;
}

运行结果及分析

5 15
5 12
4 3
7 10
2 3
6 6
背包已装容量:0
背包已装容量:1
背包已装容量:2
背包已装容量:3
背包已装容量:4
背包已装容量:5
背包中已装入物品:1
背包已装容量:6
背包中已装入物品:1
背包已装容量:7
背包中已装入物品:1
背包已装容量:8
背包中已装入物品:1
背包已装容量:9
背包中已装入物品:1
背包已装容量:10
背包中已装入物品:1
背包已装容量:11
背包中已装入物品:1
背包已装容量:12
背包中已装入物品:1
背包已装容量:13
背包中已装入物品:1
背包已装容量:14
背包中已装入物品:1
背包已装容量:15
背包中已装入物品:1
背包已装容量:0
背包已装容量:1
背包已装容量:2
背包已装容量:3
背包已装容量:4
背包中已装入物品:2
背包已装容量:5
背包已装容量:6
背包已装容量:7
背包已装容量:8
背包已装容量:9
背包中已装入物品:2
背包已装容量:10
背包已装容量:11
背包已装容量:12
背包已装容量:13
背包已装容量:14
背包中已装入物品:2
背包已装容量:15
背包已装容量:0
背包已装容量:1
背包已装容量:2
背包已装容量:3
背包已装容量:4
背包已装容量:5
背包已装容量:6
背包已装容量:7
背包已装容量:8
背包已装容量:9
背包已装容量:10
背包已装容量:11
背包已装容量:12
背包已装容量:13
背包已装容量:14
背包已装容量:15
背包已装容量:0
背包已装容量:1
背包已装容量:2
背包中已装入物品:4
背包已装容量:3
背包中已装入物品:4
背包已装容量:4
背包中已装入物品:4
背包已装容量:5
背包已装容量:6
背包已装容量:7
背包中已装入物品:4
背包已装容量:8
背包中已装入物品:4
背包已装容量:9
背包中已装入物品:4
背包已装容量:10
背包已装容量:11
背包已装容量:12
背包中已装入物品:4
背包已装容量:13
背包中已装入物品:4
背包已装容量:14
背包中已装入物品:4
背包已装容量:15
背包已装容量:0
背包已装容量:1
背包已装容量:2
背包已装容量:3
背包已装容量:4
背包已装容量:5
背包已装容量:6
背包已装容量:7
背包已装容量:8
背包已装容量:9
背包已装容量:10
背包已装容量:11
背包已装容量:12
背包已装容量:13
背包已装容量:14
背包已装容量:15
背包能装物品的最大总价值:36

《动态规划之背包问题(01背包,完全背包,多重背包)》

多重背包

问题描述

有N个物品,每种物品有num[i]个,每个物品的重量为weight[i],每个物品的价值为value[i]。现在有一个背包,它所能容纳的重量为V,问:当你面对这么多有价值的物品时,你的背包所能带走的最大价值是多少?

关键思路

通过int counts = min(i / weight[j], num[j]);限制物品的装入次数。

程序实现

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
    int N;//物品个数 5
    int V;//背包容量 15
    cin >> N >> V;
    int weight[N + 1];// 5 4 7 2 6
    int value[N + 1];// 12 3 10 3 6
    int num[N + 1];// 2 4 1 5 3
    weight[0] = value[0] = num[0] = 0;
    int maxTotalValue[V + 1]; //maxTotalValue[i]:背包已装容量为i时,背包里所装物品的最大总价值
    memset(maxTotalValue, 0, sizeof(maxTotalValue));
    for(int i = 1; i <= N; i++)
        cin >> weight[i] >> value[i] >> num[i];
    for(int j = 1; j <= N; j++)
        for(int i = V; i >= 0; i--)
            {
                cout << "背包已装容量:" << i << endl;
                if(i >= weight[j])
                    {
                        int counts = min(i / weight[j], num[j]);
                        for(int k = 0; k <= counts; k++)
                            {
                                if(maxTotalValue[i] >= k * value[j] + maxTotalValue[i - k * weight[j]])
                                    ;
                                else
                                    {
                                        maxTotalValue[i] = maxTotalValue[i - k * weight[j]] + k * value[j];
                                        cout << "背包中已装入物品:" << j << ",已装入:" << k << "个" << endl;
                                    }

                            }

                    }
                else
                    ;
            }
    cout << "背包能装物品的最大总价值:" << maxTotalValue[V] << endl;
    return 0;
}

运行结果及分析

5 15
5 12 2
4 3 4
7 10 1
2 3 5
6 6 3
背包已装容量:15
背包中已装入物品:1,已装入:1个
背包中已装入物品:1,已装入:2个
背包已装容量:14
背包中已装入物品:1,已装入:1个
背包中已装入物品:1,已装入:2个
背包已装容量:13
背包中已装入物品:1,已装入:1个
背包中已装入物品:1,已装入:2个
背包已装容量:12
背包中已装入物品:1,已装入:1个
背包中已装入物品:1,已装入:2个
背包已装容量:11
背包中已装入物品:1,已装入:1个
背包中已装入物品:1,已装入:2个
背包已装容量:10
背包中已装入物品:1,已装入:1个
背包中已装入物品:1,已装入:2个
背包已装容量:9
背包中已装入物品:1,已装入:1个
背包已装容量:8
背包中已装入物品:1,已装入:1个
背包已装容量:7
背包中已装入物品:1,已装入:1个
背包已装容量:6
背包中已装入物品:1,已装入:1个
背包已装容量:5
背包中已装入物品:1,已装入:1个
背包已装容量:4
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包中已装入物品:2,已装入:1个
背包已装容量:14
背包中已装入物品:2,已装入:1个
背包已装容量:13
背包已装容量:12
背包已装容量:11
背包已装容量:10
背包已装容量:9
背包中已装入物品:2,已装入:1个
背包已装容量:8
背包已装容量:7
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包中已装入物品:2,已装入:1个
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包已装容量:14
背包已装容量:13
背包已装容量:12
背包已装容量:11
背包已装容量:10
背包已装容量:9
背包已装容量:8
背包已装容量:7
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包中已装入物品:4,已装入:2个
背包已装容量:14
背包中已装入物品:4,已装入:2个
背包已装容量:13
背包中已装入物品:4,已装入:1个
背包已装容量:12
背包中已装入物品:4,已装入:1个
背包已装容量:11
背包已装容量:10
背包已装容量:9
背包中已装入物品:4,已装入:2个
背包已装容量:8
背包中已装入物品:4,已装入:1个
背包已装容量:7
背包中已装入物品:4,已装入:1个
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包中已装入物品:4,已装入:2个
背包已装容量:3
背包中已装入物品:4,已装入:1个
背包已装容量:2
背包中已装入物品:4,已装入:1个
背包已装容量:1
背包已装容量:0
背包已装容量:15
背包已装容量:14
背包已装容量:13
背包已装容量:12
背包已装容量:11
背包已装容量:10
背包已装容量:9
背包已装容量:8
背包已装容量:7
背包已装容量:6
背包已装容量:5
背包已装容量:4
背包已装容量:3
背包已装容量:2
背包已装容量:1
背包已装容量:0
背包能装物品的最大总价值:30

《动态规划之背包问题(01背包,完全背包,多重背包)》

    原文作者:cherryleechen
    原文地址: https://www.jianshu.com/p/e40c7a7dddd5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞