zoukankan      html  css  js  c++  java
  • 1190: [HNOI2007]梦幻岛宝珠

    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

    又一次忘记把一组数据改成多组数据了,光荣的WA了

    分层dp(听起来很高端的样子)

    直接dp是不行的,而且他告诉我们每一个w都可以拆成a*2^b,0<=b<=30,所以我们肯定就按b分组了

    f[i,j]表示体积为j*2^i再加上W二进制第i位以下的体积最多可以获得多少价值

    每一层单独dp一下,就是普通的01背包

    层与层之间还要dp一下

    f[i,j]=max(f[i,j],f[i,j-k]+f[i-1,min(k*2+e[i-1],d[i-1])])

    解释一下,d[i]表示第i层最多到体积为d[i]*2^i,这个可以算出来,就是d[i]:=sum[i]+(d[i-1]+1)>>1,sum[i]是这一层的a的总和,d[i]就是用来减少不必要的运算的

     1 var
     2     f:array[0..32,0..1010]of longint;
     3     w,v:array[0..32,0..100]of longint;
     4     a,sum,d:array[0..32]of longint;
     5     s:longint;
     6  
     7 function max(x,y:longint):longint;
     8 begin
     9     if x>y then exit(x);
    10     exit(y);
    11 end;
    12  
    13 function min(x,y:longint):longint;
    14 begin
    15     if x<y then exit(x);
    16     exit(y);
    17 end;
    18  
    19 procedure main;
    20 var
    21     i,j,l,n,k,x,y:longint;
    22 begin
    23     read(n,s);
    24     if n=-1 then halt;
    25     fillchar(f,sizeof(f),0);
    26     fillchar(a,sizeof(a),0);
    27     fillchar(sum,sizeof(sum),0);
    28     fillchar(d,sizeof(d),0);
    29     for i:=1 to n do
    30       begin
    31         read(x,y);
    32         k:=0;
    33         while x and 1=0 do
    34           begin
    35             inc(k);
    36             x:=x>>1;
    37           end;
    38         inc(a[k]);
    39         w[k,a[k]]:=x;
    40         v[k,a[k]]:=y;
    41         inc(sum[k],x);
    42       end;
    43     k:=1;
    44     while s>(1<<k-1) do
    45       inc(k);
    46     dec(k);
    47     for i:=0 to k do
    48       begin
    49         if i<>0 then d[i]:=(d[i-1]+1)>>1;
    50         inc(d[i],sum[i]);
    51         for j:=1 to a[i] do
    52           for l:=d[i] downto w[i,j] do
    53             f[i,l]:=max(f[i,l],f[i,l-w[i,j]]+v[i,j]);
    54         if i<>0 then
    55           for j:=d[i] downto 0 do
    56             for l:=0 to j do
    57               f[i,j]:=max(f[i,j],f[i,j-l]+f[i-1,min(d[i-1],l*2+(1 and (s>>(i-1))))]);
    58       end;
    59     writeln(f[k,1]);
    60 end;
    61  
    62 begin
    63     while true do
    64       main;
    65 end.
    View Code
  • 相关阅读:
    UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
    UVa 1658 (拆点法 最小费用流) Admiral
    UVa 11082 (网络流建模) Matrix Decompressing
    UVa 753 (二分图最大匹配) A Plug for UNIX
    UVa 1451 (数形结合 单调栈) Average
    UVa 1471 (LIS变形) Defense Lines
    UVa 11572 (滑动窗口) Unique Snowflakes
    UVa 1606 (极角排序) Amphiphilic Carbon Molecules
    UVa 11054 Wine trading in Gergovia
    UVa 140 (枚举排列) Bandwidth
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3590539.html
Copyright © 2011-2022 走看看