01背包问题

简介: 01背包问题

01背包问题

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0 < N, V <= 1000

0 < vi, wi <= 1000

Example 1:

Input:
4 5

1 2
2 4
3 4
4 5
Output:
8

题解思路 DP

我们定义

fi 表示从前i个物品中,选择总体积不超过j的所有物品集合的最大价值

那么

1.当我们不选择物品i时,

f[i][j] = f[i - 1][j]

2.当我们选择物品i时

f[i][j] = f[i - 1][j - v[i]] + w[i]

综上可得,

f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i])

那么,我们最终要求得的问题最终解即fn。
根据状态计算,写出代码。

code

#include <stdio.h>
#include <algorithm>
using namespace std;

int main()
{
    const int N = 1010;
    int f[N][N] = {0};
    
    int n = 0;
    int m = 0;
    
    int v[N] = {0};
    int w[N] = {0};
    
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) scanf("%d %d", &v[i], &w[i]);
    
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            f[i][j] = f[i - 1][j];
            if (j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
        }
    }
    
    printf("%d\n", f[n][m]);
    return 0;
}

代码优化

观察上述代码,我们不难发现,第一维数组f[i],只和f[i -1]相关,在遍历i的过程中,我们必先会求得f[i - 1],故可以做等价变换,将i这个维度去掉,简化代码如下

#include <stdio.h>
#include <algorithm>
using namespace std;

int main()
{
    const int N = 1010;
    int f[N] = {0};
    
    int n = 0;
    int m = 0;
    
    int v[N] = {0};
    int w[N] = {0};
    
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) scanf("%d %d", &v[i], &w[i]);
    
    for (int i = 1; i <= n; ++i) {
        for (int j = m; j >= v[i]; --j) {
            f[j] = max(f[j], f[j - v[i]] + w[i]);
        }
    }
    
    printf("%d\n", f[m]);
    return 0;
}
目录
相关文章
|
19天前
01背包问题的理解
01背包问题的理解
|
4月前
|
算法 容器
01背包问题
01背包问题
30 1
|
9月前
|
算法
动归背包2
动归背包2
42 0
|
11月前
动态规划:01背包问题
动态规划:01背包问题
71 0
|
12月前
|
算法 决策智能
背包问题——01背包|完全背包 1
背包问题——01背包|完全背包
243 0
|
12月前
背包问题——01背包|完全背包 2
背包问题——01背包|完全背包
139 0
|
机器学习/深度学习
|
机器学习/深度学习 存储 算法
【背包问题】01背包问题
给定n种物品(每种物品只有一件)和一个背包:物品i的重量是wi,其价值 为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物 品的总价值最大? 对于每种物品,只有两种选择:装(1)或者不装(0),不允许装物品的一部分
192 0
【背包问题】01背包问题