zoukankan      html  css  js  c++  java
  • 01背包变形

    传送门

    现有 N 个物品,序号分别为 1, 2, ... , N。对于每个 i (1 ≤ i ≤ N),物品 i 有一个体积 wi 和一个价值 vi

    小明想在这 N 个物品中选取一些放到背包里带回家。已知背包的容积为 W,这意味着所带物品的总体积不能超过 W

    求出小明可以带回家的物品总价值可能的最大值。

    Constraints

     

    • 输入的所有数值均为整数。
    • 1 ≤ N ≤ 100
    • 1 ≤ W ≤ 109
    • 1 ≤ wi ≤ W
    • 1 ≤ vi ≤ 103

    Input

     

    标准输入格式如下:

    N W
    w1 v1
    w2 v2
    :
    wN vN
    

    Output

     

    输出小明可以带回家的物品总价值可能的最大值。

    Sample Input 1

     

    3 8
    3 30
    4 50
    5 60
    

    Sample Output 1

     

    90
    

    把物品 1 和物品 3 带回家,此时它们的总体积为 3 + 5 = 8,总价值为 30 + 60 = 90 最大。

    Sample Input 2

     

    1 1000000000
    1000000000 10
    

    Sample Output 2

     

    10
    

    Sample Input 3

     

    6 15
    6 5
    5 6
    6 4
    6 6
    3 5
    7 2
    

    Sample Output 3

     

    17
    

    物品 2, 4 和 5 可以被带回家,此时它们的总体积为 5 + 6 + 3 = 14,总价值为 6 + 6 + 5 = 17

    如果按照普通的01背包的板子的复杂的是O(n*w),但是这个题的1 ≤ W ≤ 109,所以肯定会超时

    那怎么办呢,注意这个题的每一个体积1 ≤ vi ≤ 103,就是说总体积不会超过1e5,

    然后你设置一个dp[i],为价值为i的最小体积,然后从sumv到1判断dp[i]是否小于W

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn=1e6+100;
    ll n,w[maxn],v[maxn];
    ll dp[maxn];
    ll sum=0;
    ll W;
    int main(){
        cin>>n>>W;
        for(int i=1;i<=n;i++){
            cin>>w[i]>>v[i];
            sum+=v[i]; 
        }
        memset(dp,0x3f3f3f3f,sizeof(dp));
        dp[0]=0;
        for(int i=1;i<=n;i++){
            for(int j=sum;j>=v[i];j--){
                dp[j]=min(dp[j],dp[j-v[i]]+w[i]); 
            }
        } 
        for(int i=sum;i>=1;i--){
            if(dp[i]<=W){
                cout<<i<<endl;
                break;
            } 
        }
    } 
  • 相关阅读:
    [转]Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
    ubuntu wifi连接出现Network service discovery disabled的解决办法
    使用java实现对称加密解密(AES),非对称加密解密(RSA)
    [转] mysql分区性能初探
    CyclicBarrier和CountDownLatch的使用
    oom 和 jvm crash的问题
    使用单元素枚举实现单例
    【转】mysql 计划事件
    用Linkedhashmap的LRU特性及SoftReference软引用构建二级缓存
    动态生成正则表达式
  • 原文地址:https://www.cnblogs.com/lipu123/p/14505611.html
Copyright © 2011-2022 走看看