0-1背包问题

我们两清 提交于 2020-02-04 19:06:49

0-1背包问题

问题描述:有个容量为m的背包和n∈[1, 100]个物品,每个物品的重量为w[i]∈[1, 100],价格为p[i]∈[1, 100],问如何装入物品,使得在不超过背包容量的情况下,使得装下的物品的价格最大?

这题有三种解法,咱们先介绍动态规划的解法。

构造一个一维数组f[10005],f[i]表示背包容量为i时,背包里的物品价格的最大值

于是我们有递推式f[i] = max( f[i], f[i - w] + p);

动态规划

采用自顶而下的遍历

#include <bits/stdc++.h>
using namespace std;
int f[10005];
int main()
{
    int w[105], p[105], n, m;
    while(~scanf("%d%d", &n, &m) && n) {
        memset(w, 0, sizeof(w));
        memset(p, 0, sizeof(p));
        memset(f, 0, sizeof(f));
        for(int i = 0;i < n; ++i) scanf("%d%d", &w[i], &p[i]);
        for(int i = 0;i < n; ++i)
            for(int j = m;j >= w[i]; --j)
                f[j] = max(f[j], f[j - w[i]] + p[i]);
        printf("%d\n", f[m]);
    }
    return 0;
}

第二种是用递归法,跟动态规划相似的思路。

递归法

也是自顶而下的。

#include <bits/stdc++.h>
using namespace std;
int n, w[105], p[105];
void solve(int index, int free_space)
{
    if(index < 0 || free_space <= 0) return 0;
    int ret = solve(index - 1, free_space);
    if(w[index]<=free_space) ret=max(ret,solve(index-1,free_space-w[index]));
    return ret;
}
int main()
{
    while(~scanf("%d%d", &n, &m)) {
        memset(w, 0, sizeof(w));
        memset(p, 0, sizeof(p));
        for(int i = 0;i < n; ++i) scanf("%d%d", &w[i], &p[i]);
        printf("%d\n", solve(n - 1, m));
    }
}

优化下递归就成了记忆化搜索。

记忆化搜索

#include <bits/stdc++.h>
using namespace std;
int n, w[105], p[105], me[105][105];
void solve(int index, int free_space)
{
    if(index < 0 || free_space <= 0) return 0;
    if(me[index][free_space]) return me[index][free_space];
    int ret = solve(index - 1, free_space);
    if(w[index]<=free_space) ret=max(ret,solve(index-1,free_space-w[index]));
    me[index][free_space] = ret;
    return ret;
}
int main()
{
    while(~scanf("%d%d", &n, &m)) {
        memset(w, 0, sizeof(w));
        memset(p, 0, sizeof(p));
        memset(me, 0, sizeof(me));
        for(int i = 0;i < n; ++i) scanf("%d%d", &w[i], &p[i]);
        printf("%d\n", solve(n - 1, m));
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!