问题
有n个物品,分别给出其重量、价值和数量,背包容量为m,求在背包容量内的物体价值最大值为多少?注意:每件物品最多取的数目不超过规定数目
首先暴力一下
我们知道完全背包
的暴力就是在第三重循环中设置其数目
那么这里,我们可以直接将条件换为k<=c[i]
状态转移方程为
和完全背包一致
那么我们来看下代码
#include<stdio.h>
#define N 100
int w[N],v[N],p[N][N],c[N];//p为最大价值,s为选择与否
int main(){
int n,m,i,j,k;
//printf("请输入物品种类数目和背包大小:");
scanf("%d %d",&n,&m);
//printf("请输入各物品所占体积、价值和数量:");
for(i=1;i<=n;i++){
scanf("%d %d %d",&w[i],&v[i],&c[i]);
}
for(i=1;i<=n;i++){//选择前i个物品
for(j=1;j<=m;j++){//增大容量
for(k=0;k<=j/w[i]&&k<=c[i];k++){
if(k*v[i]+p[i-1][j-k*w[i]]>p[i][j]){//比较
p[i][j]=k*v[i]+p[i-1][j-k*w[i]];
}
}
}
}
printf("最大价值为:%d\n",p[n][m]);
return 0;
}
似乎也没有太大不一样
接着我们把它优化一下
和完全背包差不多,但是,有数目规定
所以这里分析和完全背包差不多啦
指路:完全背包
注意:这里第二重循环i倒序求解
所以,代码如下:
#include<stdio.h>
#define N 10000
int w[N],v[N],p[N],c[N];//p为最大价值,s为选择与否
int main(){
int n,m,i,j,k;
//printf("请输入物品种类数目和背包大小:");
scanf("%d %d",&n,&m);
//printf("请输入各物品所占体积、价值和数量:");
for(i=1;i<=n;i++){
scanf("%d %d %d",&w[i],&v[i],&c[i]);
}
for(i=1;i<=n;i++){//选择前i个物品
for(j=m;j>=w[i];j--){//倒序求解
for(k=0;k<=j/w[i]&&k<=c[i];k++){
if(k*v[i]+p[j-k*w[i]]>p[j]){//选择后比较
p[j]=k*v[i]+p[j-k*w[i]];
}
}
}
}
printf("最大价值为:%d\n",p[m]);
return 0;
}