HRBUST 1377 分组背包

来源:互联网 发布:linux下使用anaconda 编辑:程序博客网 时间:2024/04/28 15:06

给出一些物品,有三个属性,分别是 价值,重要度,所属主件,主件只要钱够就可以买,附件必须拥有该附件的主件才可以购买

每个主件最多有2种配件

求在给定钱数下能得到的最大的价值*重要度的和


给出拥有的总钱数m,能够买的总物品数n

然后n行,每行三个整数,该物品的价格a,该物品的重要度b,该物品所属与的主件的编号c,如果编号为0代表它是一个主件,否则它是属于主件c

求sum(a[i]*b[i]);也就是最大的能够买到的 物品的价值*重要度 的和.


物品有依赖关系,属于分组背包..

对于每个主件,一共可能有4种选择..

_1   不买

_2  只买该主件

_3  买该主件+1配件

_4  买该主件+2配件

输入完预处理一下,把每个主件的可以选择的决策压缩..

然后对每个主件进行 01背包..

需要注意的就是,01的时候内层循环dp[j]在更新的时候有4种选择,不能在每种选择中就更新dp[j],需要记录最大值,再更新.

背包九讲再次v5...


#include<stdio.h>#include<string.h>#include<string>#include<map>using namespace std;struct ss{    int ans1,ans2,ans3,ans4,tot;    int x1,x2,lv,lv1,lv2,x;    int a,b,c;}a[10005];int dp[32005+1];int max(int a,int b){    if(a>b)return a;    else return b;}int main(){    int m,n;    while(scanf("%d %d",&m,&n)!=EOF){        int lv,val,f,tot=1;        memset(dp,0,sizeof(dp));        for(int i=0;i<70;i++)a[i].tot=0;        tot=1;        for(int i=1;i<=n;i++){            scanf("%d %d %d",&a[i].a,&a[i].b,&a[i].c);            val=a[i].a,lv=a[i].b,f=a[i].c;            if(a[i].c==0){                a[i].x=val,a[i].lv=lv,a[i].ans1=val*lv;            }        }        for(int i=1;i<=n;i++){             f=a[i].c,val=a[i].a,lv=a[i].b;             if(f!=0){                if(a[f].tot==0){                    a[f].x1=val,a[f].lv1=lv;                    a[f].ans2=a[f].ans1+a[f].x1*a[f].lv1;                    a[f].tot++;                }else {                    a[f].x2=val,a[f].lv2=lv;                    a[f].ans3=a[f].ans1+a[f].x2*a[f].lv2;                    a[f].ans4=a[f].ans2+a[f].ans3-a[f].ans1;                    a[f].tot++;                }            }        }        int tp,mx1,mx2,mx3,mx4;        for(int i=1;i<=n;i++){                if(a[i].c==0){                for(int j=m;j>=0;j--){                    mx1=mx2=mx3=mx4=0;                    if(j>=a[i].x)mx1=max(dp[j],dp[j-a[i].x]+a[i].ans1);                    if(a[i].tot>0&&(j>=(a[i].x+a[i].x1)))mx2=max(dp[j],dp[j-a[i].x-a[i].x1]+a[i].ans2);                    if(a[i].tot>1&&(j>=(a[i].x+a[i].x2)))mx3=max(dp[j],dp[j-a[i].x-a[i].x2]+a[i].ans3);                    if(a[i].tot>1&&(j>=(a[i].x+a[i].x1+a[i].x2)))mx4=max(dp[j],dp[j-a[i].x-a[i].x1-a[i].x2]+a[i].ans4);                    dp[j]=max(max(max(max(mx1,mx2),mx3),mx4),dp[j]);                }}        }        printf("%d\n",dp[m]);    }return 0;}


原创粉丝点击