1052. 0-1背包问题

aiden
#include <iostream>
#include <algorithm>
using namespace std;

int bag[21][100001];

int w[21];
int p[21];

int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int n, M;
        cin >> n >> M;
        for (int i = 1; i <= n; ++i)
            cin >> w[i] >> p[i];
        for (int k = 1; k <= n; ++k)
        {
            for (int cap = 1; cap <= M; ++cap)
            {
                if (w[k] > cap)
                {
                    //第k件太重
                    bag[k][cap] = bag[k - 1][cap];
                }
                else
                {
                    //装或不装
                    bag[k][cap] = max(bag[k - 1][cap - w[k]] + p[k], bag[k - 1][cap]);
                }
            }
        }
        cout << bag[n][M] << endl;
    }
    return 0;
}
SmallY

0-1背包问题,基础题,空间可以优化成O(M)的,基本不会爆内存的

T = int(input())
for _ in range(T):
    n, m = map(int, input().split())
    items = []
    for i in range(n):
        items.append([int(i) for i in input().split()])
    res = [0]*(m+1)
    for i in range(n):
        for j in range(m, -1, -1):
            if j-items[i][0] >= 1:
                res[j] = max(res[j], res[j-items[i][0]]+items[i][1])
    print(res[m])
MasterKiller

此处Shut down MasterX 记录

10175101245

n的范围比较小,直接用递归穷举选择每个物品是否放入的二叉树貌似就完事了,而且耗时好像还不多(0.012s),大概数据大了会炸吧……
不过数据大了的情况下,动态规划的做法是否也可能爆内存呢……

SmallY

不会,看我上面的回答

zzpzbl

清零啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

scott_ch

啊啊啊啊,我也想说这句啊啊

zhangoneone

wrong answer

cd106224
//dp[i][v]代表将前i个物品放入背包为v大小的最大值
//dp[i][v]=max{dp[i-1][v],dp[i-1][v-weight[i]]+value[i]};
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
struct Node {
    int weight;
    int value;
};
Node a[21];
int dp[21][100010];
int main() {
    int num;
    cin >> num;
    while (num--) {
        memset(dp, 0, sizeof(dp));
        memset(a, 0, sizeof(a));
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i].weight >> a[i].value;
        }
        for (int i = 1; i <= n; ++i) {
            for (int v = 1; v <= m; ++v) {
                if (v >= a[i].weight) {
                    dp[i][v] = max(dp[i - 1][v], dp[i - 1][v - a[i].weight] + a[i].value);
                }
                else {
                    dp[i][v] = dp[i - 1][v];
                }
            }
        }
        cout << dp[n][m] << endl;
    }
    return 0;
}
scott_ch

数据很好,直接dfs

cd106224

dfs+剪枝

Fifnmar

wow,OJ 上真的有 0-1 背包的样题呀。

int main() {
    uint32_t t; std::cin >> t;
    for (uint32_t query = 0; query < t; ++query) {
        uint32_t n, m; std::cin >> n >> m;
        vector<uint32_t> w(n), v(n), dp(m + 1, 0);
        for (uint32_t i = 0; i < n; ++i)
            std::cin >> w[i] >> v[i];
        for (uint32_t i = 0; i < n; ++i)
            for (uint32_t j = m; j >= w[i]; --j)
                if (dp[j] < dp[j - w[i]] + v[i])
                    dp[j] = dp[j - w[i]] + v[i];
        printf("%u\n", dp[m]);
    }
}
你当前正在回复 博客/题目
存在问题!