加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

luoguP1064 金明的预算方案 (有依赖的背包问题)

发布时间:2020-12-14 05:03:23 所属栏目:百科 来源:网络整理
导读:题目链接:https://www.luogu.org/problemnew/show/P1064 这是一个有依赖的背包问题,属于01背包的变式。这题还好,每个主件最多有2个附件,那么在对主件进行背包的时候,决策就不再是两个,而是五个。 01背包的决策: 不选; 选; 这个题目的决策: 不选; 只

题目链接:https://www.luogu.org/problemnew/show/P1064

这是一个有依赖的背包问题,属于01背包的变式。这题还好,每个主件最多有2个附件,那么在对主件进行背包的时候,决策就不再是两个,而是五个。

01背包的决策:

  1. 不选;  
  2. 选;

这个题目的决策:

  1. 不选;
  2. 只选主件;
  3. 选主件和附件1;
  4. 选主件和附件2;
  5. 选主件,附件1和附件2;

这里需要先判断选附件的决策是不是可行,即如果当前容量能放下附件1或附件2或附件1和附件2,才考虑状态转移。

因此这题的状态转移方程有4个:

  f[j]=max(f[j],f[j-mv[i]]+mc[i]);
? ???? f[j]=max(f[j],f[j-mv[i]-av[i][1]]+mc[i]+ac[i][1]);

   f[j]=max(f[j],f[j-mv[i]-av[i][2]]+mc[i]+ac[i][2]);
?????? f[j]=max(f[j],f[j-mv[i]-av[i][1]-av[i][2]]+mc[i]+ac[i][1]+ac[i][2]);
其中mv表示主件的费用数组,mc表示主件的价值(费用×重要度)数组,av表示附件的费用数组,ac表示附件的价值数组。

av[i][0]表示主件i的附件个数,av[i][1/2]表示主件i的附件1/2的费用,ac[i][1/2]表示主件i的附件1/2的价值。

AC代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 int n,m;
 6 int mv[65],mc[65],av[65][3],ac[65][3];
 7 int f[32005];
 8 
 9 int main(){
10     scanf("%d%d",&n,&m);
11     int v,p,q;
12     for(int i=1;i<=m;i++){
13         scanf("%d%d%d",&v,&p,&q);
14         if(!q){
15             mv[i]=v;
16             mc[i]=v*p;
17         }
18         else{
19             av[q][0]++;
20             av[q][av[q][0]]=v;
21             ac[q][av[q][0]]=v*p;
22         }
23     }
24     for(int i=1;i<=m;i++)
25         if(mv[i]){
26             for(int j=n;j>=mv[i];j--){
27                 f[j]=max(f[j],f[j-mv[i]]+mc[i]);
28                 if(j>=mv[i]+av[i][1])
29                     f[j]=max(f[j],f[j-mv[i]-av[i][1]]+mc[i]+ac[i][1]);
30                 if(j>=mv[i]+av[i][2])
31                     f[j]=max(f[j],f[j-mv[i]-av[i][2]]+mc[i]+ac[i][2]);
32                 if(j>=mv[i]+av[i][1]+av[i][2])
33                     f[j]=max(f[j],f[j-mv[i]-av[i][1]-av[i][2]]+mc[i]+ac[i][1]+ac[i][2]);
34             }
35         }
36     printf("%dn",f[n]);
37     return 0;
38 }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读