• Bone Collector II HDU


    题意:

    01背包,找出第k最优解

    题解:

    对于01背包最优解我们肯定都很熟悉

    第k最优解的话也就是在dp方程上加一个维度来存它的第k最优解(dp[i][j]代表,体积为i能获得的第j最大价值)

    对于每一个物品只有两种选择情况

    1、把这个物品加入背包

    2、不要这个物品

    那么它的前k种最优解也是由n种物品的这两个选择组成的

    假设总体积是4,现在有两种物品,求第2最大值

    1、体积1,价值3

    2、体积1,价值2

    最开始dp状态:

    体积:    1  2  3  4

    第1最大值:0  0  0  0

    第2最大值:0  0  0  0

    x、y数组是用来记录他从上一个状态转移过来的前k最大值。

    x数组代表需要这个物品的时候的前k最大值

    y数组代表不需要这个物品的时候前k最大值

    下面演示过程:

    体积为4的时候

    x[1]=v[4-1][1]+3 =3

    x[2]=v[4-1][2]+3 =3

    y[1]=v[4][1]=0

    y[2]=v[4][2]=0

    下面那个while循环的意思就是给x数组和y数组这4个数(因为我要求第2(k)最大值,所以是2*2(2*k)个数)从大到小排序之后去重,从中挑出来2(k)个赋值给v[j][1],v[j][2](v[j][1]...v[j][k])

    排序后:3 3 0 0,去重后3 0

    那么v[4][1]=3,v[4][2]=0

    可能有些人不明白while代码中怎么会有去重操作,我们来看一下

    给v[4][1]赋值的时候因为x[1]=3>y[1]=0,所以很自然v[4][1]=3

    这个时候给v[4][2]赋值,因为x[2]=3>y[1]=0,所以v[4][2]=3。但是因为v[4][1]==v[4][2]所以循环不会结束

    我们来看一下循环结束条件while((m<=f || n<=f) && o<=f)

    之有前k个最优值都找到之后循环会结束,或者x和y数组所有值都用完了

    所以还是去给v[4][2]赋值,那么又因为x[3]=y[3]=-1。所以x[3]=-1<y[0]=0,那么v[4][2]=0

    这个时候循环就结束了

    我上面解释的时候用的是前k最大值,代码中用的字母是f。。。

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 int q[105],w[105],v[1005][35],x[1005],y[1005];
     4 int main()
     5 {
     6     int a,s,sum,d,f,g;
     7     scanf("%d",&a);
     8     while(a--)
     9     {
    10         memset(v,0,sizeof(v));
    11         scanf("%d%d%d",&s,&d,&f);
    12         for(int i=1; i<=s; ++i)
    13         {
    14             scanf("%d",&w[i]);
    15             sum+=w[i];
    16         }
    17         for(int i=1; i<=s; ++i)
    18             scanf("%d",&q[i]);
    19         for(int i=1; i<=s; ++i)
    20         {
    21             for(int j=d; j>=q[i]; --j)
    22             {
    23                 int k;
    24                 for(k=1; k<=f; ++k)
    25                 {
    26                     x[k]=v[j-q[i]][k]+w[i];
    27                     y[k]=v[j][k];
    28                 }
    29                 x[k]=y[k]=-1;
    30                 int m,n,o;
    31                 m=n=o=1;
    32                 while((m<=f || n<=f) && o<=f)
    33                 {
    34                     if(x[m]>y[n])
    35                     {
    36                         v[j][o]=x[m];
    37                         ++m;
    38                     }
    39                     else
    40                     {
    41                         v[j][o]=y[n];
    42                         ++n;
    43                     }
    44                     if(v[j][o]!=v[j][o-1]) ++o;
    45                 }
    46             }
    47         }
    48         printf("%d
    ",v[d][f]);
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    English Dictionary site for ODE and OALD
    vmic environment
    makefile
    the diference between include and import
    windows 工具命令 cmd
    python namespace
    shell cmd args
    ROE, ROC
    IP
    链接及常用软件
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12082343.html
Copyright © 2020-2023  润新知