Description

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

Input

输入文件中包含多组数据。每组数据的格式如下:第一行是两个正整数n和W,1≤n≤100,1≤W≤2^30,分别表示宝石的数目和最多能带走的宝石重量。接下来的n行,每行有两个正整数weighti和valuei,1≤weighti≤2^30, 0≤valuei≤2^30,分别表示第i颗宝石的重量和价值,且保证weighti能写成a*2^b(1≤a≤10,0≤b≤30)的形式。同一行的两个正整数之间用空格隔开。最后一组数据的后面有两个-1,表示文件的结束。这两个-1并不代表一组数据,你不需对这组数据输出结果。并且输入文件中数据的组数不超过20。

Output

对于输入的每组数据,输出一个整数C,表示小P最多能带走的宝石的总价值。每个结果整数C单独占一行,且保证C不会超过2^30。

Sample Input

4 10
8 9
5 8
4 6
2 5
4 13
8 9
5 8
4 6
2 5
16 75594681
393216 5533
2 77
32768 467
29360128 407840
112 68
24576 372
768 60
33554432 466099
16384 318
33554432 466090
2048 111
24576 350
9216 216
12582912 174768
16384 295
1024 76
-1 -1

Sample Output

14
19
1050650
 

题解:

显然这是一个01背包,但是体积容积都特别大。

事实上,每颗宝石体积在2进制情况下的有效位数都特别有限,可以对体积按位dp。

F[i,j]表示当前DP到第i位,使用j*2^(i-1)体积可以得到的最大价值。对于i的阶段,只要用b=i-1的宝石去DP,然后进位转移到下一阶段。

因为a<=10,n<=100,j最多为1000。

注意考虑上界,需额外开一个数组表示所考虑有效位数之后的数都在W对应范围内的情况。

代码:

  1. uses math;
  2. var
  3. i,j,k,l,n,m,ii,ww:longint;
  4. tot,w:int64;
  5. a:array[..,..,..]of int64;
  6. s:array[..]of longint;
  7. b:array[..,..]of int64;
  8. t:array[..]of int64;
  9. begin
  10. while true do
  11. begin
  12. readln(n,w); tot:=;
  13. //w:=;
  14. if n=- then break;
  15. for i:= to n do
  16. begin
  17. readln(b[i,],b[i,]);
  18. b[i,]:=;
  19. while b[i,] mod = do begin b[i,]:=b[i,] div ; inc(b[i,]); end;
  20. end;
  21. for i:= to n- do
  22. for j:=i+ to n do
  23. if b[i,]>b[j,] then begin t:=b[i]; b[i]:=b[j]; b[j]:=t; end;
  24. fillchar(a,sizeof(a),);
  25. if n=- then break;
  26. l:=;
  27. while w> do
  28. begin
  29. inc(l); s[l]:=w mod ;
  30. w:=w div ;
  31. end;
  32. ii:=;
  33. for i:= to l do
  34. begin
  35. for j:= to do
  36. if(s[i-]=)or(j mod =)then
  37. begin
  38. a[,i,j div ]:=max(a[,i,j div ],a[,i-,j]);
  39. a[,i,j div ]:=max(a[,i,j div ],a[,i-,j]);
  40. end;
  41. for j:= to do
  42. begin
  43. a[,i,(j div )+]:=max(a[,i,(j div )+],a[,i-,j]);
  44. if j mod = then
  45. a[,i,j div ]:=max(a[,i,j div ],a[,i-,j]);
  46. end;
  47. while(ii<=n)and(b[ii,]<=i)do
  48. begin
  49. for j:=-b[ii,] downto do
  50. begin
  51. a[,i,j+b[ii,]]:=max(a[,i,j+b[ii,]],a[,i,j]+b[ii,]);
  52. a[,i,j+b[ii,]]:=max(a[,i,j+b[ii,]],a[,i,j]+b[ii,]);
  53. end;
  54. inc(ii);
  55. end;
  56. for j:= to do begin a[,i,j]:=max(a[,i,j],a[,i,j-]);
  57. a[,i,j]:=max(a[,i,j-],a[,i,j]); end;
  58. end;
  59. writeln(max(a[,l,],a[,l,]));
  60. end;
  61. end.

BZOJ1190[HNOI2007]梦幻岛宝石的更多相关文章

  1. 【题解】 bzoj1190: [HNOI2007]梦幻岛宝珠 (动态规划)

    bzoj1190,懒得复制,戳我戳我 Solution: 这道题其实是一个背包(分组背包),但是由于数字比较大,就要重新构造dp式子.啃了三天才懂. \(dp[i][j]\)表示背包容积为\(j*2^ ...

  2. bzoj1190 [HNOI2007]梦幻岛宝珠 动态规划

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

  3. bzoj1190 [HNOI2007]梦幻岛宝珠

    传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1190 [题解] 首先,我们把所有物品都分解成$a\times 2^b$的形式,然后把物品按 ...

  4. bzoj1190 [HNOI2007]梦幻岛宝珠 背包

    题目 https://lydsy.com/JudgeOnline/problem.php?id=1190 题解 好神仙的一道题啊. 既然 \(w_i = a_i\cdot 2^{b_i}\),那么不妨 ...

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

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

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

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

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

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

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

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

  9. [HNOI2007]梦幻岛宝珠(背包)

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

随机推荐

  1. linux 安装nginx

    linux系统为Centos6.5 64位 nginx为1.4.7 从http://nginx.org/download/上下载相应的版本 解压 tar -zxvf nginx-1.4.7.tar.g ...

  2. java web学习总结(七) -------------------HttpServletResponse对象(一)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应,那我们要 ...

  3. GetEnumerator();yield

    GetEnumerator()方法的实质实现: 说明:只要一个集合点出GetEnumerator方法,就获得了迭代器属性,就可以用MoveNext和Current来实现foreach的效果,如上图. ...

  4. (原) 2.2 ZkClient使用

    本文为原创文章,转载请注明出处,谢谢 ZkClient使用 1.jar包引入,演示版本为0.8,非maven项目,可以下载jar包导入到项目中 <dependency> <group ...

  5. JQ中的方法、事件及动画

    css( ) 除了可以为元素添加样式外,还可用来查询元素,某样式值alert($('.cls1').css('width')); //100px(返回带单位的值)注意:原生CSS样式中有-的去掉并且将 ...

  6. 关于arcgis engine的工作空间(IWorkspace)和选择集(FeatureSelection)

    1.通过某个WorkspaceFactoryClass(例如AccessWorkspaceFactoryClass)拿到工作空间工厂接口,这时的OpenFromFile方法可以直接打开mdb类型文件, ...

  7. View and Data API Tips: how to make viewer full screen

    By Daniel Du If you have not heard of View and Data API, here is the idea, the View & Data API e ...

  8. include的用法例子,以及include+merge的用法例子

    [include+LinearLayout]的使用例子 AndroidIncludeLayout.java package com.AndroidIncludeLayout; import andro ...

  9. 判断用户输入的银行卡号是否正确--基于Luhn算法的格式校验

    开发中,有时候,为了打造更好的用户体验,同时减轻服务器端的压力,需要对于一些如,手机号码,银行卡号,身份证号码进行格式校验 下面是判断银行卡号输入是否正确的代码(基于Luhn算法的格式校验): iOS ...

  10. android 性能分析案例

    本章以实际案例分析在android开发中,性能方面的优化和处理.设计到知识点有弱引用,memory monitor,Allocation Tracker和leakcanary插件. 1.测试demo ...