微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

hdu 3449 有依赖的背包

背景:1——TL按照背包九讲的把没一个依赖组转用01背包转化成物品集合,然后又用分组背包的方法来做,超时。优化无果,借鉴别人思路ac。

正确写法思路:先不管必须选盒子这个前提,按照01背包的思想把物品选一次到thing[]数组中,然后再把再强项对每个数据都买盒子,这样thing中只有thing[Box....v]能买起盒子,且thing[k]=thing[k-Box]+0 ,盒子的价值是0.所以转移方程:F[j]=max{F[j],thing[k-Box]} (F[j]表示不选盒子和盒子里的物品的价值,thing[k-Box]表示选择盒子和盒子内的物品所能达到的最大价值)

题目注解见代码

#include <iostream>
#include<cstdio>
#include<cstring>
#define INF 100009
using namespace std;
int thing[INF],F[INF];
int n,v,Box,mi,co[20],wo[20],sum_Box;



int main(void){
    while(~scanf("%d%d",&n,&v)){
        memset(F,sizeof(F));
        for(int i=0;i < n;i++){
            scanf("%d%d",&Box,&mi);
            for(int j=0;j < mi;j++){
                scanf("%d%d",&co[j],&wo[j]);
            }
            memcpy(thing,F,sizeof(F));    //继承上次的状态。
            for(int i=0;i < mi;i++){    //在不考虑选择盒子的情况下,01背包式自由选择附件。
                for(int j=v;j >= co[i];j--){
                    thing[j]=max(thing[j],thing[j-co[i]]+wo[i]);
                }
            }
            for(int i=0;i <= v;i++) F[i]=max(F[i],thing[i-Box]);  /*减去盒子费用的转移:这里其实是把,自由选择下的F[Box...v],当做选了盒子之后的F[1...v-Box]
        }                                                           这样就能满足:先必须选择一个盒子,再选择用01背包的方式选择一个物品的条件了*/
        printf("%d\n",F[v]);
    }
    return 0;
}


将附件集合转化为物品组的超时代码

#include <iostream>
#include<cstdio>
#include<cstring>
#define INF 100009
using namespace std;
int thing[INF],sum_Box;

void zeroonebag(void){
     for(int j=0;j < mi;j++){
         for(int k=sum_Box;k >= co[j];k--){
             thing[k]=max(thing[k],thing[k-co[j]]+wo[j]);
         }
     }
}

int main(void){
    while(~scanf("%d%d",&mi);
            sum_Box=0;
            for(int j=0;j < mi;j++){
                scanf("%d%d",&wo[j]);
                sum_Box+=co[j];
            }
            sum_Box=min(v-Box,sum_Box);
            memset(thing,sizeof(thing));
            if(Box >= v) continue;
            zeroonebag();    //用01背包将附件集合转化为物品组。
            for(int j=v;j >= 1;j--){
                for(int k=0;k <= sum_Box;k++){
                    if(j-Box-k >= 0) F[j]=max(F[j],F[j-Box-k]+thing[k]);
                }
            }
        }
        printf("%d\n",F[v]);
    }
    return 0;
}

原文地址:https://www.jb51.cc/javaschema/284921.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐