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
  • 相关阅读:
    toj 2975 Encription
    poj 1797 Heavy Transportation
    toj 2971 Rotating Numbers
    zoj 2281 Way to Freedom
    toj 2483 Nasty Hacks
    toj 2972 MOVING DHAKA
    toj 2696 Collecting Beepers
    toj 2970 Hackle Number
    toj 2485 Card Tric
    js页面定位,相关几个属性
  • 原文地址:https://www.cnblogs.com/3200Pheathon/p/11616039.html
Copyright © 2011-2022 走看看