• 动态规划:二维费用背包


    顾名思义,二维费用的背包中的每种物品有两种费用

    设f[i][v][u]表示前i件物品付出两种代价分别为v和u时可获得的最大价值

    那么我们很容易给出状态转移方程,加一维状态即可

    f[i][v][u]=max{f[i-1][v][u],f[i-1][v-a[i]][u-b[i]]+w[i]}

    在这里,如果每种物品只可以取一次采用类似于01背包滚动数组的循环方式,即逆序循环

    如果每种物品可以取无数次采用完全背包滚动数组的循环方式,顺序循环

    如果有多重背包的方式进行二进制优化,拆分物品

    除此之外,我们要考虑满包的情况

    下面我们以RQNOJ中多多看DVD(加强版)这道题为例,来举一个具体的例子

     1 //M是第一个限制条件,每个的费用均为1,满包 
     2 //L是第二个限制条件, 每个的费用为t[i]
     3 #include<iostream>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 const int INF=0x7fffffff;
     8 const int maxn=105,maxm=105,maxl=1005;
     9 int N,M,L;
    10 int t[maxn],w[maxn];
    11 int ans=0;
    12 int f[maxl][maxn];
    13 void dp()
    14 {
    15     for(int i=0;i<=L;i++)
    16     for(int j=0;j<=M;j++)
    17         f[i][j]=-INF;
    18     for(int i=0;i<=L;i++)
    19         f[i][0]=0;
    20     //01背包逆向,完全背包正向 
    21     for(int i=1;i<=N;i++)
    22     for(int j=L;j>=t[i];j--)
    23     for(int k=M;k>=1;k--)
    24         f[j][k]=max(f[j][k],f[j-t[i]][k-1]+w[i]);
    25     ans=f[L][M];
    26     if(ans<0)
    27         ans=0;
    28 }
    29 int main()
    30 {
    31     cin>>N>>M>>L;
    32     for(int i=1;i<=N;i++)
    33         cin>>t[i]>>w[i];
    34     dp();
    35     cout<<ans<<endl;
    36     return 0;
    37 }

    可以看出二维背包是对前面所述的几种背包的一个综合的考量

  • 相关阅读:
    Python基础知识之4——三大控制结构
    Python基础知识之3——运算符与表达式
    Python基础知识之2——字典
    常用的数据分析方法汇总
    关于Windows10企业版的激活方法
    插补法图像压缩
    MouseHover-鼠标停留伴随内容提示
    移动端viewport模版
    Ajax的跨域请求
    Json用途
  • 原文地址:https://www.cnblogs.com/aininot260/p/9308659.html
Copyright © 2020-2023  润新知