杭电-2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)

来源:互联网 发布:靠谱的网络兼职 编辑:程序博客网 时间:2024/06/03 14:15

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191

相比于01背包和完全背包,多重背包由于每种物品的个数是固定的,因此要多了一层循环,用来变更物品的取用个数。

但是三重循环有时候可能会出现超时之类的问题~所以我们可以将其转化成01背包问题后再进行二进制优化

下面是《背包九讲》给出的模板,因为是背包基础题,所以这道题直接用模板就搞定勒

def MultiplePack( F , C , W , M )if C · M ≥ VCompletePack( F , C , W )returnk := 1while k < MZeroOnePack( kC , kW )M := M − kk := 2kZeroOnePack( C · M , W · M )

解题代码:

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;int dp[110];struct meat{    int price;    int weight;    int bag;};struct meat mym[110];int n,m;void CompletePack(int weight,int price){  for(int i=price;i<=n;i++)  {    dp[i]=max(dp[i],dp[i-price]+weight);  }}void ZeroOnePack(int weight,int price){  for(int i=n;i>=price;i--)  {      dp[i]=max(dp[i],dp[i-price]+weight);  }}void MultiplePack(struct meat my_meat[]){  for(int i=1;i<=m;i++)  {    if(my_meat[i].price*my_meat[i].bag>=n)      CompletePack(my_meat[i].weight,my_meat[i].price);    else    {      int k=1;      while(k<my_meat[i].bag)      {        ZeroOnePack(k*my_meat[i].weight,k*my_meat[i].price);        my_meat[i].bag-=k;        k=k*2;      }      ZeroOnePack(my_meat[i].bag*my_meat[i].weight,my_meat[i].bag*my_meat[i].price);    }  }}int main(){    int tests;    scanf("%d",&tests);    while(tests--)    {        memset(dp,0,sizeof(dp));        memset(mym,0,sizeof(mym));        scanf("%d %d",&n,&m);        for(int i=1;i<=m;i++)            {              scanf("%d%d%d",&mym[i].price,&mym[i].weight,&mym[i].bag);            }        MultiplePack(mym);        printf("%d\n",dp[n]);    }    return 0;}

0 0
原创粉丝点击