码迷,mamicode.com
首页 > 其他好文 > 详细

宝物筛选

时间:2019-10-23 11:59:31      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:clu   多重   tchar   tac   组成   href   for   ==   iostream   

传送门:https://www.luogu.org/problem/P1776

(多重背包)

很久就想用二进制拆分做一下了,这道题本来是用单调队列优化可惜蒟蒻我不会。

于是我就用二进制拆分牺牲空间复杂度换来了时间复杂度。

任何一个数都可以拆成二进制(其实不鬼畜)

e.g. 15=1+2+4+8    7=1+2+4 而拆出的这些数可以组成比这个数小的任意值。

所以代码如下

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<stack>
 5 #include<cstring>
 6 #include<cmath>
 7 using namespace std;
 8 int n,w;
 9 struct thing{
10     int v,w; 
11 }lis[1000005];
12 int tot;
13 int f[1000005];
14 inline int kd()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
18     while(ch>=0&&ch<=9){x=x*10+(ch^48);ch=getchar();}
19     return x*f;
20 }
21 int main()
22 {
23     n=kd(),w=kd();
24     for(register int i=1;i<=n;i++)
25     {
26         int x=1;
27         int a=kd(),b=kd(),c=kd();
28         while(c-x>=0)//二进制拆分本尊 
29         {
30             c-=x;
31             lis[++tot].w=x*a;
32             lis[tot].v=x*b;
33             x<<=1;
34         }
35         if(c!=0)//判断是否还有剩下的 
36         {
37             lis[++tot].w=c*a;
38             lis[tot].v=c*b;
39         }
40     }
41     for(register int i=1;i<=tot;i++)//普通的01背包乖乖 
42     {
43         for(register int j=w;j>=lis[i].v;j--)
44         {
45             f[j]=max(f[j],f[j-lis[i].v]+lis[i].w);
46         }
47     }
48     cout<<f[w];
49 }

 

  

宝物筛选

标签:clu   多重   tchar   tac   组成   href   for   ==   iostream   

原文地址:https://www.cnblogs.com/1129-tangqiyuan/p/11725103.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!