• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

yongchaoD

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

H - 宝物筛选(多重背包+二进制优化)

题目来源:https://www.luogu.com.cn/problem/P1776
//
题意:多重背包板子题
//
b站讲解:【算法讲解075【必备】背包dp-多重背包、混合背包】https://www.bilibili.com/video/BV1Nz4y1c71M?vd_source=edd8d483423d58308aefa72fbec9bd22
//
思路:多重背包朴素方法就是再加一层for循环用来遍历每个物品的数量,但是一看物品数量范围1e5,会超时的。这里就用二进制优化,将多重背包转化为01背包。不是每件商品有很多件嘛,我们可以将不同数量的相同物品组成一个新的商品就行了,比如1号商品有34件,重量为2,价值为1,可以组成1号商品(1), 2号商品(2),3号商品(4),4号商品(8)...括号里面的数字代表由几件1号商品合成的,这样每种物品就可以优化成log级别了,时间复杂度:O(背吧容量*sum(log物品1数量+log物品2数量+log物品3数量...))。
//
题解:

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e3+9;
int v[N],w[N];
int dp[40009];
signed main()
{
    int n,T;
    cin>>n>>T;
    int V,W,M,cnt=0;//V:价值  W:重量  M:数量
    for(int i=1;i<=n;i++){
        cin>>V>>W>>M;
        for(int k=1;k<=M;k<<=1){
            v[++cnt]=k*V;
            w[cnt]=k*W;
            M-=k;
        }
        if(M>0){
            v[++cnt]=M*V;
            w[cnt]=M*W;
        }
    }

     //完全背包+二进制优化 ==> 01背包
     for(int i=1;i<=cnt;i++){
         for(int j=T;j>=0;j--){
             if(j>=w[i]){
                 dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
             }
         }
     }
     cout<<dp[T]<<'\n';
    return 0;
}

posted on 2024-08-27 09:40  yongchaoD  阅读(24)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3