• 【DP合集】背包 bound


    N 种物品,第 i 种物品有 s i 个,单个重量为 w i ,单个价值为 v i 。现有一个限重为 W 的背包,求能容 纳的物品的最大总价值。

    Input

    输入第一行二个整数 N , W ( N ≤ 1000 , M ≤ 10000) 。 
    接下来 N 行,每行三个整数 s i,w i,v i ,描述一种物品。

    Output

    输出一行一个整数,描述能容纳的物品的最大总价值。保证答案不会超过2311231−1 。

    题解:

    单个单个枚举会超时,所以可以用二进制优化,就是因为如果我们可以将任意一个十进制数化成二进数,所以我可以把n个一样的背包,拆成二进制数上对于1的数的数量个背包,所以就把n个背包合并成logn个大背包,如果还不会可以参考ACM P217。
     
    代码
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int dp[100000],v[100000],w[10000],len=0;
     
    void cl(){
        memset(dp,0,sizeof(dp));
        memset(v,0,sizeof(v));
        memset(w,0,sizeof(w));
    }
     
    int main(){
        cl();
        int n,m;                                    
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            int s,ww,vv,x=1;
            scanf("%d%d%d",&s,&ww,&vv);
            while(s-x>0){
                v[++len]=vv*x;
                w[len]=ww*x;
                s-=x;
                x*=2;
            }
            if(s){
                v[++len]=vv*s;
                w[len]=ww*s;
            }
        }
        dp[0]=0;
        for(int i=1;i<=len;i++)
        for(int j=m;j>=w[i];j--)
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        printf("%d",dp[m]);
    }
  • 相关阅读:
    composer使用git作为仓储
    monolog记录日志
    lumen laravel response对象返回数据
    lumen中间件 Middleware
    AcWing 901. 滑雪
    leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
    acwing 902. 最短编辑距离
    ACWING 844. 走迷宫
    leetcode 5199. 交换字符串中的元素
    AcWing 836. 合并集合
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7192510.html
Copyright © 2020-2023  润新知