FZU2214 Knapsack problem--01背包

来源:互联网 发布:朋友圈推广软件 编辑:程序博客网 时间:2024/06/16 12:20

原题链接:http://acm.fzu.edu.cn/problem.php?pid=2214

这题不能按照传统01背包来做,它的容量太大,数组会爆掉。注意到物品个数较小,而且价值和最大只有5000,所以可以逆向思维,求得对应价
值下最小的重量,即dp[i]表示总价值为i的最小重量是多少,则dp[j] = min(dp[j] , dp[j-val[i]]+vol[i]);最后从sum(物品总价值开始判
断)开始,找到第一个小于等于b(容量)的v即可。。。

#include<iostream>#include<stdio.h>#include<algorithm>using namespace std;#define INF 1000000005int t;int n, b;int sum;int w[505];int v[505];int dp[5005];int main(){    scanf("%d", &t);    while (t--)    {        sum = 0;        scanf("%d%d", &n, &b);        for (int i = 1; i <= n; i++)        {            scanf("%d%d", &w[i], &v[i]);            sum += v[i];        }        dp[0] = 0;        for (int i = 1; i <= sum; i++)                dp[i] = INF;        for (int i = 1; i <= n; i++)        {            for (int j = sum; j >= v[i]; j--)            {                if (dp[j - v[i]] + w[i] <= b)  //大于b没有意义                    dp[j] = min(dp[j], dp[j - v[i]] + w[i]);            }        }        for (int i = sum; i >= 0; i--)        {            if (dp[i] <= b)            {                printf("%d\n", i);                break;            }        }    }    return 0;}
1 0
原创粉丝点击