题目:
有n种物品和一个容量为v的背包
第i种物品 最多s[i]件
每件体积为v[i]
价值为w[i]
求可装的最大价值;
注:v s w n 的值都小于100;
1 暴力解法:
思想:
代码实现:
#include<bits/stdc++.h>
using namespace std;
int m,n,i,j;
int f[1010];
int v,k,s,w;
int main()
{
cin>>n>>m;
for(i=1;i<=n;i++)
{
cin>>v>>w>>s;
for(j=m;j>=v;j--)
{
for(k=0;k<=s&&v*k<=j;k++)
{
f[j]=max(f[j],f[j-v*k]+w*k);
}
}
}
cout<<f[m]<<endl;
return 0;
}
2 优化做法:
思想:(二进制优化)
代码实现:
#include<bits/stdc++.h>
using namespace std;
int m,n,i,j;
typedef pair<int,int>pll;
vector<pll>goods;
int v,s,w,k;
int f[2010];
pll x;
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&v,&w,&s);
int k=1;
while(k<=s)
{
s-=k;
x={v*k,w*k}; //该整体中含k个该物品 整体的质量和价值都要乘k
goods.push_back(x);
k*=2;
}
if(s>0)goods.push_back({v*s,w*s}); //用二的N次方表示后剩余的数
}
//分堆之后 按01背包来处理;
for(auto e:goods)
{
int a=e.first;
int b=e.second;
for(j=m;j>=a;j--)
{
f[j]=max(f[j],f[j-a]+b);
}
}
printf("%d",f[m]);
return 0;
}