这题是在01背包问题的基础上,扩充了重量,需要用时间换空间。

思路:

1.仔细看题,注意到重量wi为a*2^b(a<=10,b<=30),很容易想到要按 b 分开做背包的DP。接下来的重点就是怎么使DP从b-1继承到b。

2.再仔细看题,发现只有一次询问,那么就可以在这个W上做文章——依W的大小进行所有的DP。由于是按b的大小进行DP,所以把数都看成二进制位来继承和转移,每对一组 b 相同的数做完后,就略去这一二进制位。

实现:

1.“去位”:若W的二进制数上第 i 位为1,那么这时背包里已经放的物品的重量的第 i 位为0或1都无所谓,装得了;若W的二进制数上第 i 位为0,那么背包已有的重量的第 i 位为1就要从二进制的前一位借一个“1”拿来用。

2.对每组 b 进行DP时,直接用最大的背包容量N*wi(mW),之后转移时再按W进行修改就行了。

其中,以上实现可行的原因是:

对于每个第 i 位,它处于一个很“尴尬”的境地,它的前一位一给就是给“1”,对于它就是“2”了,多了也无需退回去。因为对于每个第 j 位,它的下一位根本就帮不了它,贡献“1”对于它也只是“0.5”,是没有用的。因此要略去某一位时,只需干脆地按W是否能满足它这一位的需求来对自己的前一位进行调整。

  1. 1 #include<cstdio>
  2. 2 #include<cstdlib>
  3. 3 #include<cstring>
  4. 4 #include<iostream>
  5. 5 #include<algorithm>
  6. 6 using namespace std;
  7. 7
  8. 8 typedef long long LL;
  9. 9 const int N=110,M=30,mW=1000;
  10. 10 int n,W;
  11. 11 struct node{int w,v,a,b;}s[N];
  12. 12 LL f[M+10][mW+10];
  13. 13
  14. 14 bool cmp(node x,node y)
  15. 15 { return x.b<y.b; }
  16. 16 LL mmax(LL x,LL y)
  17. 17 { return x>y?x:y; }
  18. 18
  19. 19 int main()
  20. 20 {
  21. 21 while (1)
  22. 22 {
  23. 23 scanf("%d%d",&n,&W);
  24. 24 if (n==-1&&W==-1) break;
  25. 25 for (int i=1;i<=n;i++)
  26. 26 {
  27. 27 scanf("%d%d",&s[i].w,&s[i].v);
  28. 28 s[i].a=s[i].w,s[i].b=0;
  29. 29 while (s[i].a%2==0) s[i].a/=2,s[i].b++;
  30. 30 }
  31. 31 sort(s+1,s+1+n,cmp);
  32. 32 int l,r;
  33. 33 l=1;
  34. 34 memset(f,0,sizeof(f));
  35. 35 for (int i=0;i<=M;i++)
  36. 36 {
  37. 37 r=l-1;//
  38. 38 while (r<n && s[r+1].b==i) r++;//<n
  39. 39 for (int j=l;j<=r;j++)
  40. 40 for (int k=mW;k>=s[j].a;k--)
  41. 41 f[i][k]=mmax(f[i][k],f[i][k-s[j].a]+s[j].v);
  42. 42 for (int j=0;j<=mW;j++)//or (int j=mW;j>=0;j--)
  43. 43 if (W&(1<<i)) f[i+1][j>>1]=mmax(f[i+1][j>>1],f[i][j]);
  44. 44 else f[i+1][(j+1)>>1]=mmax(f[i+1][(j+1)>>1],f[i][j]);
  45. 45 l=r+1;
  46. 46 }
  47. 47 printf("%lld\n",f[31][0]);
  48. 48 }
  49. 49 return 0;
  50. 50 }

【bzoj 1190】梦幻岛宝珠(DP)的更多相关文章

  1. BZOJ 1190 梦幻岛宝珠(分组01背包)

    跑了7000ms... 这是个体积和价值都超大的背包.但是体积保证为a*2^b的(a<=10,b<=30)形式.且n<=100. 于是可以想到按b来分组.这样的话每组最多为a*n*2 ...

  2. [BZOJ 1190][HNOI2007]梦幻岛宝珠

    1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1057  Solved: 611[Submit][Stat ...

  3. BZOJ 1190 [HNOI2007]梦幻岛宝珠(背包)

    1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1385  Solved: 798[Submit][Stat ...

  4. E - 梦幻岛宝珠 HYSBZ - 1190 变形01背包 难

    E - 梦幻岛宝珠 HYSBZ - 1190 这个题目我觉得很难,看题解都看了很久. 首先可以得到一个大概的思路就是分组,每一个数都可以分成 a*2^b  所以把b相同的数都分成一个组. 在每一组内部 ...

  5. 【BZOJ1190】[HNOI2007]梦幻岛宝珠 分层背包DP

    [BZOJ1190][HNOI2007]梦幻岛宝珠 Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值. ...

  6. luogu 3188 [HNOI2007]梦幻岛宝珠

    LINK:梦幻岛宝珠 时隔多日 我再次挑战这道题.还是以失败告终. 我觉得这一道背包真的有点难度 这是一个数量较少 但是价值和体积较大的背包. 通常的01背包 要不就是体积小 要么是价值小 但这道题给 ...

  7. BZOJ.1190.[HNOI2007]梦幻岛宝珠(分层背包DP)

    题目链接 把重量表示为\(a\times2^b\)的形式,然后按\(b\)排序. 从高到低枚举每一位,\(f[i]\)表示当前位容量为\(i\)时的最大价值(容量即\(a\times2^{bit}\) ...

  8. 1190: [HNOI2007]梦幻岛宝珠 - BZOJ

    Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值. 数据范围:N<=100;W<=2^30 ...

  9. [HNOI2007]梦幻岛宝珠 「套路:分层 $DP$」

    显然直接 \(01\) 背包会超时并且超空间 套路:分层 \(DP\) 「考虑将每个子结构看作一层(也就是包含了不止 \(1\) 个物品的信息),并且大层不会对小层造成影响,可以考虑先进行每一层的自我 ...

随机推荐

  1. python_字典(dict)

    dict 一.结构: info = { "key":"value", "key":"value" } print(inf ...

  2. 【排序基础】1、选择排序法 - Selection Sort

    文章目录 选择排序法 - Selection Sort 为什么要学习O(n^2)的排序算法? 选择排序算法思想 操作:选择排序代码实现 选择排序法 - Selection Sort 简单记录-bobo ...

  3. CentOS系统内核升级(在线 离线)

    为什么要升级内核? Docker 在CentOS系统中需要安装在 CentOS 7 64 位的平台,并且内核版本不低于 3.10:CentOS 7.× 满足要求的最低内核版本要求,但由于 CentOS ...

  4. vue2.0、vue3.0不同之处

    一.响应式赋值操作不同 Vue2.0 1.通过data返回对象做相应: 2.对复杂的对象或数组下的属性等深层次的改变需要通过$set的方式. Vue3.0 1.ref实现简单的实现响应,通过value ...

  5. C++中输出变量类型的方法

    C++中输出变量类型的方法 在c++中输出变量或者数据类型,使用typeid().name()的方法.如下例子: #include <iostream> #include <stri ...

  6. 转 Fiddler2 下断点修改HTTP报文

    文章转自:https://www.cnblogs.com/zhengna/p/10861893.html 一 Fiddler中设置断点修改HTTP请求 方法1:全局断点.Rules-->Auto ...

  7. 浅谈自动化构建之grunt

    自动化构建 开发行业的自动化构建 一句话把源代码转化为生产代码,作用是脱离运行环境兼容带来的问题开发阶段使用提高效率的语法,规范 和标准,构建转换那些不被支持的特性转化成能够执行的代码. 一.简单的自 ...

  8. nothreading use single threaded

    threading:   # ThreadingMixIn.daemon_threads indicates how threads will behave on an   # abrupt shut ...

  9. 题解 CF620E 【New Year Tree】

    有关dfs序的例题,需要有一定的位运算基础 题面 给定一个树,树上有颜色,将某一子树的颜色统一修改,求子树中颜色的数量 Solution 子树修改,子树求和,dfs序的知识(类似区间修改区间求和) 考 ...

  10. JS 实现一个实时动态校验,将输入格式错误的显示为红色背景

    功能描述: 源码: 功能描述: 实时动态校验,如果输入的格式错误,将弹窗提示输入格式错误并将背景展示为红色. 源码: 前台: <hy:formfield name="cxfdl&quo ...