• 分组背包&&有依赖的背包


    这两种背包问题可以看成是完全背包(其实是多重背包),其状态转移方程 F[i][j]=max{f[i-1][j-k*v[i]]+k*w[i]}   仍然适用

    对于分组背包,由于存在冲突,只能从一个组选一件,所以完全可以这样思考:

    把一组看做是一个物品,选取组中的第i件看成是选取i个该物品。

    这样就转换为完全背包求解了,只是将k*w[i]k*v[i]分别映射为一个函数(对应关系)。

    对于有依赖背包,可以将同一系列的物品看做一组,将不同的取法看做组中的原件,即可转化为分组背包,进而转化为完全背包。

    P.S.     0/1 背包也可以看做完全背包,其中k[0,1];多重背包也是完全背包。所以可见,完全背包的应用和变形还是非常广的,应该灵活掌握。

    附上Rqnoj P6 金明的预算方案 代码。这道题是典型的有依赖背包,也可作为有依赖背包的模板

    Rqnoj P6
     1 //rqnoj 6
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 int m,n,e;
    5 int v[100][5],c[100][5];
    6 int vb[100],cb[100],fb[100];
    7 int f[100][32000+1];
    8 int main()
    9 {
    10 scanf("%d%d",&n,&m);
    11 int i,j,k,a,b,max;
    12 for (i=1;i<=m;i++)
    13 {
    14 scanf("%d%d%d",&vb[i],&cb[i],&fb[i]);
    15 cb[i]*=vb[i];
    16 }
    17 for (i=1;i<=m;i++)
    18 {
    19 if (fb[i]==0)
    20 {
    21 a=0;b=0;
    22 v[e][1]=vb[i];
    23 c[e][1]=cb[i];
    24 for (j=1;j<=m;j++)
    25 {
    26 if (fb[j]==i)
    27 {if (a==0) a=j; else b=j;}
    28 v[e][2]=vb[a]+vb[i];
    29 c[e][2]=cb[a]+cb[i];
    30 v[e][3]=vb[b]+vb[i];
    31 c[e][3]=cb[b]+cb[i];
    32 v[e][4]=vb[a]+vb[b]+vb[i];
    33 c[e][4]=cb[a]+cb[b]+cb[i];
    34 }
    35 e++;
    36 }
    37 }
    38 for (i=1;i<=m;i++)
    39 for (j=1;j<=n;j++)
    40 {
    41 max=0;
    42 for (k=0;k<5;k++)
    43 if (j-v[i-1][k]>=0&&f[i-1][j-v[i-1][k]]+c[i-1][k]>max)
    44 max=f[i-1][j-v[i-1][k]]+c[i-1][k];
    45 f[i][j]=max;
    46 }
    47 printf("%d\n",f[m][n]);
    48 system("pause");
    49 return 0;
    50 }
    51
    52 //5种取法(z=主件,1,2=1,2附件):0 z z+1 z+2 z+1+2
  • 相关阅读:
    网页 js 获取DPI pxTomm
    利用自定义属性实现js点击事件 委托
    鼠标移动div时禁止选中div中的文字的方法
    关于if简写语句优化的方法
    .clearfix::after(清除浮动)
    js 事件委托
    清空共享池
    oracle中scott用户权限不足
    安装完Oracle 12C数据库,scott账户过期,解锁方法
    Vulnhub靶场-Me Tomcat Host 学习笔记
  • 原文地址:https://www.cnblogs.com/loveidea/p/2436306.html
Copyright © 2020-2023  润新知