背包问题---怎么选取物品,可以使得背包装的物品价值最大?

原文:

https://zhuanlan.zhihu.com/p/567560364

1)0-1背包问题的描述

现在有四种物品,每种物品只有1件,它们的重量与价值如下表。

现在有一个背包,总容量为8。问怎么选取物品,可以使得背包装的物品价值最大?

物品编号 物品重量 物品价值 物品数量
1 2 3 1
2 3 4 1
3 4 5 1
4 5 8 1

(2)多重背包问题的描述

现在有四种物品,每种物品有若干件,它们的重量与价值如下表。

现在有一个背包,总容量为8。问怎么选取物品,可以使得背包装的物品价值最大?

物品编号 物品重量 物品价值 物品数量
1 2 3 2
2 3 4 2
3 4 5 2
4 5 8 2

(3)完全背包问题的描述

现在有四种物品,每种物品有无数件,它们的重量与价值如下表。

现在有一个背包,总容量为8。问怎么选取物品,可以使得背包装的物品价值最大?

物品编号 物品重量 物品价值 物品数量
1 2 3 无数件
2 3 4 无数件
3 4 5 无数件
4 5 8 无数件

一、0-1背包问题

一、0-1背包问题

思路:对于每件物品,由于是不可分割的放入,所以,就有两种情况:该物品放入背包与该物品不放入背包;为了将以上问题求解出来,我们需要设置好状态以及状态转移方程。

(1)定义状态

DP[k][w]:表示当背包剩余容量为w,现在有前k件物品可放的情况下,背包所能装物品的最大价值。

那么,状态确定好了,上面所描述的题目中,只要求出DP[4][8]就可以了。

DP[k][w]怎么求呢,这就是状态转移方程的问题。

(2)状态转移方程

我们先将状态转移方程写出来吧,就是:

DP[k][w] 等于下列两种情况:

①DP[k][w]=DP[k-1][w],当第k件物品的重量大于w时

②DP[k][w]=max(DP[k-1][w],DP[k-1][w-wi]),当第k件物品的重量不大于w时

背包问题---怎么选取物品,可以使得背包装的物品价值最大?_第1张图片

#include 

#define N 10010
#define V 10010
#define MAX(a,b) ((a) > (b) ? (a) : (b))

int dp[N][V];
int n, v;       //n:物品数量,v:背包实际容量 
int weight[N];   //第n件物品的重量 
int value[N];    //第n件物品的价值 

void knap_01()
{
    for (int i = 1;i <= n; i++)
        for (int j = 1; j <= v; j++) {
            if (weight[i] > j) {
                dp[i][j] = dp[i-1][j];
            } else {
                dp[i][j] = MAX(dp[i - 1][j - weight[i]] + value[i], dp[i - 1][j]);
            }
    }
}

int main()
{
    scanf("%d %d", &n, &v);
    for(int i = 1;i <= n; i++) {
        scanf("%d", &weight[i]);
    }

    for(int i = 1;i <= n; i++) {
        scanf("%d", &value[i]);
    }

    knap_01();
    printf("dp[%d][%d]=%d\n", n, v, dp[n][v]);

    return 0;
}

你可能感兴趣的:(华为OD机考真题(C,C++,python),算法,背包)