宝物筛选_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}cnt[i]$

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

       附上二进制优化代码

     

 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

猜你喜欢

转载自www.cnblogs.com/3200Pheathon/p/11616039.html
今日推荐