17-又见01背包

/*                                        又见01背包
时间限制:1000 ms  |  内存限制:65535 KB
难度:3

描述
        有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W
    的物品,求所有挑选方案中物品价值总和的最大值。
      1 <= n <=100
      1 <= wi <= 10^7
      1 <= vi <= 100
      1 <= W <= 10^9

输入
    多组测试数据。
    每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和 vi。
输出
    满足题意的最大价值,每组测试数据占一行。
样例输入

4 5
    2 3
    1 2
    3 4
    2 2

样例输出

7

来源
    飘谊系列
上传者
    TC_张友谊
*/
//http://www.cnblogs.com/chenzhiyin/p/5513258.html
//由于重量太大了,开数组绝对内存超了,有观察到价值很小,故可以转化思路反过来求,
//动态规划分析:最少要拿总价值一定,求所拿的最小质量(根据"最大能拿总重量一定,求能拿的最大价值"原理推导)

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int dp[10005];
int w[105], v[105];
int W;
int main(){
    int n;
    while(~scanf("%d%d", &n, &W)){  //超时了一下午,竟然是因为忘了取反号!!!
        int sum = 0;
        for(int i = 1; i <= n; i++){        
            scanf("%d%d", &w[i], &v[i]);
            sum += v[i];
        }    
        //初始化dp
        for(int i = 1; i <= sum; i++){    //初始化dp时对应价值位上的重量初始为最大值,注意dp[0]要保证是0
            dp[i] = 1000000005;           //不是随意设的
        }        
        for(int i = 1; i <= n; i++){
            for(int j = sum; j >= 1; j--){
                if(j >= v[i])
                    dp[j] = min(dp[j], dp[j - v[i]] + w[i]); //可以看出刚好j = v[i]时就是dp[j]和w[i]大小的的比较
                else
                    dp[j] = min(dp[j], w[i]);
            }
        }
        int big = 1;
        while(big <= sum && dp[big] <= W){
            big++;
        }
        printf("%d\n", big - 1);
    }
    return 0;
}

时间: 2024-10-01 05:05:24

17-又见01背包的相关文章

NYIST 860 又见01背包

又见01背包时间限制:1000 ms | 内存限制:65535 KB难度:3 描述 有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 的物品,求所有挑选方案中物品价值总和的最大值. 1 <= n <=100 1 <= wi <= 10^7 1 <= vi <= 100 1 <= W <= 10^9输入多组测试数据. 每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和 vi. 输出满足题

NYOJ-860 又见01背包

又见01背包 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 的物品,求所有挑选方案中物品价值总和的最大值. 1 <= n <=100 1 <= wi <= 10^7 1 <= vi <= 100 1 <= W <= 10^9 输入 多组测试数据. 每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和

nyoj860--又见01背包**************

又见01背包 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 的物品,求所有挑选方案中物品价值总和的最大值. 1 <= n <=100 1 <= wi <= 10^7 1 <= vi <= 100 1 <= W <= 10^9 输入 多组测试数据.每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和

背包 [NYOJ 860] 又见01背包

又见01背包 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 的物品,求所有挑选方案中物品价值总和的最大值. 1 <= n <=100 1 <= wi <= 10^7 1 <= vi <= 100 1 <= W <= 10^9 输入 多组测试数据. 每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和

南阳oj 860又见01背包

又见01背包 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 的物品,求所有挑选方案中物品价值总和的最大值. 1 <= n <=100 1 <= wi <= 10^7 1 <= vi <= 100 1 <= W <= 10^9 输入 多组测试数据. 每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和

nyoj 860 又见01背包 【另类01背包】

分析: 首先这道题不能当做普通的01背包问题,因为W <= 10^9,开不了,那么大的数组,肯定有其他的思路,观察一下我们知道价值v小的很,最大100, 那我们就可以利用这一点,拿价值 之和作为原来的质量之和, 但是有一点要注意:因为题意是要在质量不超过W的范围内,找出最大的价值,我们现在是以最大的价值求质量,那么仔细分析一下,我们就能想明白,要以某价值i的背包存放尽量小的质量,这样反过来分析一下就可以知道,较小的质量有个较大的价值序号,这样完全满足题意了, 最后还有一点,就是价值背包的每一个(

nyoj860 又见01背包(背包变形)

题目860 题目信息 执行结果 本题排行 讨论区 又见01背包 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述     有n个重量和价值分别为wi 和 vi 的 物品.从这些物品中选择总重量不超过 W 的物品,求全部挑选方案中物品价值总和的最大值. 1 <= n <=100 1 <= wi <= 10^7 1 <= vi <= 100 1 <= W <= 10^9 输入 多组測试数据. 每组測试数据第一行输入,n 和 W .

又见01背包

1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 using namespace std; 5 int dp[10001]; 6 int v[105],w[105]; 7 int main() 8 { 9 int n,W,i,j,sum; 10 while(~scanf("%d%d",&n,&W)) 11 { 12 sum=0; 13 for(int i=1

NYOJ 820 又见01背包 (价值和重量互换)

链接:click here 题意: 描述     有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 的物品,求所有挑选方案中物品价值总和的最大值. 1 <= n <=100 1 <= wi <= 10^7 1 <= vi <= 100 1 <= W <= 10^9 输入 多组测试数据. 每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和 vi. 输出 满足题意的最大价值,每组测试数据占