zoukankan      html  css  js  c++  java
  • 宝物筛选_NOI导刊2010提高(02)(二进制拆分/优先队列优化多重背包)


    题目描述

    终于,破解了千年的难题。小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎。但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物。看来小FF只能含泪舍弃其中的一部分宝物了……小FF对洞穴里的宝物进行了整理,他发现每样宝物都有一件或者多件。他粗略估算了下每样宝物的价值,之后开始了宝物筛选工作:小FF有一个最大载重为W的采集车,洞穴里总共有n种宝物,每种宝物的价值为v[i],重量为w[i],每种宝物有m[i]件。小FF希望在采集车不超载的前提下,选择一些宝物装进采集车,使得它们的价值和最大。

    输入格式

    第一行为一个整数N和w,分别表示宝物种数和采集车的最大载重。

    接下来n行每行三个整数,其中第i行第一个数表示第i类品价值,第二个整数表示一件该类物品的重量,第三个整数为该类物品数量。

    输出格式

    输出仅一个整数ans,表示在采集车不超载的情况下收集的宝物的最大价值。

    输入输出样例

    输入 #1
    4 20
    3 9 3
    5 9 1
    9 4 2
    8 1 3
    输出 #1
    47

    说明/提示

    对于30%的数据:n≤∑m[i]≤10^4;0≤W≤10^3。

    对于100%的数据:n≤∑m[i]≤10^5;

    0 <w≤4*10^4:1≤n<100。

          多重背包在不优化的情况下复杂度为:m(背包体积)$sum_{i=1}^{n}wcnt$

          二进制优化复杂度:m(背包体积)log($sum_{i=1}^{n}wcnt$)

           附上二进制优化代码

         

     1 #include<bits/stdc++.h>
     2 #define re register int
     3 #define maxn 40000+5
     4 #define maxn1 1600+5
     5 
     6 
     7 using namespace std;
     8 int f[maxn],n,m;
     9 int wei[maxn1],val[maxn1];
    10 int  weight,value,wcnt,cnt;
    11 int main()
    12 {
    13     ios::sync_with_stdio(false); 
    14     cin>>n>>m;
    15     for(re i=1;i<=n;i++)
    16     {
    17         cin>>value>>weight>>wcnt;
    18         for(re tmp=1;tmp<=wcnt;tmp<<=1)
    19         {
    20             val[++cnt]=value*tmp;
    21             wei[cnt]=weight*tmp;
    22             wcnt-=tmp;
    23         }
    24         if(wcnt) val[++cnt]=value*wcnt,wei[cnt]=weight*wcnt;
    25     }
    26     for(re i=1;i<=cnt;i++)
    27     for(re j=m;j>=wei[i];j--)
    28     f[j]=max(f[j],f[j-wei[i]]+val[i]); 
    29     cout<<f[m];
    30     return 0;
    31 }
    View Code

        单调队列优化复杂度:m*$sum_{i=1}^{n}wcnt$

        具体理解可以参见https://blog.csdn.net/flyinghearts/article/details/5898183

     1 #include<bits/stdc++.h>
     2 #define re register int
     3 #define maxn 40000+5
     4  
     5 using namespace std;  
     6 int  n,m;
     7 int f[maxn],cnt[maxn],q[maxn];
     8 int ans;
     9 int sum,maxcnt;
    10 int weight,value,wcnt,tmp,tmp1;
    11 int main()
    12 {
    13     ios::sync_with_stdio(false);
    14     cin>>n>>m;
    15     for(re i=1;i<=n;i++)
    16     {
    17         cin>>value>>weight>>wcnt;
    18         if(weight==0)  {
    19             tmp+=value*wcnt;
    20             continue;
    21         }
    22         sum=min(wcnt,m/weight);
    23         for(re j=0;j<weight;j++)
    24         {
    25             maxcnt=(m-j)/weight;
    26             int head=1,tail=0;
    27             for(re k=0;k<=maxcnt;k++)
    28             {
    29                 int tmp1=f[j+k*weight]-k*value;
    30                 while(head<=tail&&q[tail]<=tmp1)
    31                 tail--;
    32                 q[++tail]=tmp1;
    33                 cnt[tail]=k;
    34                 while(head<=tail&&cnt[head]+sum<k) head++;
    35                 f[j+k*weight]=max(f[j+k*weight],q[head]+k*value);
    36                 ans=max(ans,f[j+k*weight]);
    37             }
    38         }
    39     }
    40     cout<<tmp+ans;
    41     return 0;
    42 }
    View Code
  • 相关阅读:
    VIVADO固化
    Keil MDK 编译器 AC5 和 AC6 优化选项重要内容和区别
    STM32时钟
    STlink/v2中SWD模式连线方式
    搭载M33内核,支持最新蓝牙5.1,晚到的DA1469x生正逢时
    超全国内外蓝牙芯片原厂总结(含芯片型号)
    芯片封装类型大全
    国务院办公厅关于2012年部分节假日安排的通知
    美国摇滚乐队Metro致敬黄家驹,全粤语翻唱Beyond经典《海阔天空》
    国务院办公厅发布2010年部分节假日安排通知
  • 原文地址:https://www.cnblogs.com/3200Pheathon/p/11616039.html
Copyright © 2011-2022 走看看