​题目链接​多重背包变01背包

题解:
一道简单的01背包变形,看样子每一个都是又数量但又不是无限的,所以把每一个种类的有限数量,变成单独的个体即可,说是多重背包其实就是01背包的变形而已

AC代码:

#include<bits/stdc++.h>
//hdu 2191
//多重背包转化为01背包
#define maxn 10005
using namespace std;
int dp[maxn];
int n,m,id;
struct node
{
int pr,wi;//价格和重量
} temp[maxn];
void s_dp()
{
memset(dp,0,sizeof(dp));
for(int i=1; i<id; i++)
{
for(int j=n; j>=temp[i].pr; j--)
{
dp[j]=max(dp[j],dp[j-temp[i].pr]+temp[i].wi);
}
}
printf("%d\n",dp[n]);



}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
id=1;
int pr,wi,num;
for(int i=1; i<=m; i++)
{
scanf("%d %d %d",&pr,&wi,&num);
while(num--)
{
// id++;
temp[id].pr=pr;
temp[id].wi=wi;
id++;
}
}
// printf("%d\n",id);
s_dp();
}
}

01背包+二进制优化

所谓二进制优化:
不过是把背包数量按二进制的分解 举个栗子:
​​​5:1 2 3​​ 把 5 分解为1 2 3三个单体包 对于数据更大的效果更明显

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn 1005
struct node
{
int pr,wi;//价格,重量
}temp[maxn];
int dp[maxn];//完全背包+二进制优化
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
int pr,n,id=1;
scanf("%d %d",&pr,&n);
for(int i=1;i<=n;i++)
{
int i_pr,i_wi,num;
scanf("%d %d %d",&i_pr,&i_wi,&num);
for(int j=1;j<=num;j<<=1)
{
temp[id].pr=i_pr*j;
temp[id].wi=i_wi*j;
id++;
num-=j;
}
if(num>0)
{
temp[id].pr=i_pr*num;
temp[id].wi=i_wi*num;
id++;
}
}
for(int i=1;i<id;i++)
{
for(int j=pr;j>=temp[i].pr;j--)
{
dp[j]=max(dp[j],dp[j-temp[i].pr]+temp[i].wi);
}
}
printf("%d\n",dp[pr]);

}
}