P1776 寶物篩選_NOI導刊2010提高(02)(揹包的二進位制優化)

自為風月馬前卒發表於2017-07-17

題目描述

終於,破解了千年的難題。小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。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define lli long long int 
 7 using namespace std;
 8 const int MAXN=100001;
 9 const int maxn=0x3f;
10 void read(int &n)
11 {
12     char c='+';int x=0;bool flag=0;
13     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
14     while(c>='0'&&c<='9')
15     x=(x<<1)+(x<<3)+c-48,c=getchar();
16     flag==1?n=-x:n=x;
17 }
18 int n,m;
19 struct node
20 {
21     int va,we,num;
22 }a[MAXN];
23 int dp[MAXN];
24 int  main()
25 {
26     read(n);read(m);
27     for(int i=1;i<=n;i++)
28     {
29         read(a[i].va);
30         read(a[i].we);
31         read(a[i].num);
32     }
33     for(int i=1;i<=n;i++)
34     {
35         int left=(a[i].num);
36         for(int k=1;left;k<<=1)
37         {
38             if(k>left)
39                 k=left;
40             left-=k;
41             int w=a[i].we*k;
42             int v=a[i].va*k;
43             for(int j=m;j>=w;j--)
44                 dp[j]=max(dp[j],dp[j-w]+v);
45         }
46     }
47     printf("%d",dp[m]);
48     return 0;
49 }

 

相關文章