背包问题
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 82 测试通过 : 31
总提交 : 82 测试通过 : 31
比赛描述
试设计一个用回溯法搜索子集空间树的函数。该函数的参数包括结点可行性判定函数和上界函数等必要的函数,并将此函数用于解0-1背包问题。
0-1 背包问题描述如下:给定n 种物品和一个背包。物品i 的重量是 wi ,其价值为 v i,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
在选择装入背包的物品时,对每种物品i只有2 种选择,即装入背包或不装入背包。不能将物品i 装入背包多次,也不能只装入部分的物品i。
0-1 背包问题形式化描述:给定C>0, Wi >0, Vi >0,1≤i≤n,要求n 元0-1向量( x1 ,x2 ,…, xn ),xi∈{0,1},1≤i≤n,使得 达到最大
输入
第一行有2个正整数n和c。n是物品数,c是背包的容量。接下来的1 行中有n个正整数,表示物品的价值。第3 行中有n个正整数,表示物品的重量。
输出
计算出装入背包物品的最大价值和最优装入方案。
样例输入
5 10
6 3 5 4 6
2 2 6 5 4
样例输出
15
1 1 0 0 1
提示
题目来源
算法设计与实验题解
#include<stdio.h>
#include<stdlib.h>
int f(int c,int n,int *w,int *v,int i,bool *b,bool *mb,int mV){
if(c<=0 || i==n)
return mV;
int p,q;
b[i]=0;
p = f(c,n,w,v,i+1,b,mb,mV);
if(c>w[i]){
q = f(c-w[i],n,w,v,i+1,b,mb,mV)+v[i];
if(q>p){
p=q;
b[i]=1;
}
}
if(p>mV){
for(int k=0; k<n; k++)
mb[i]=b[i];
mV=p;
}
return mV;
}
int main(){
int n,c,*w,*v,i,mV;
bool *b,*mb;
while(scanf("%d%d",&n,&c)==2){
w=(int*)malloc(sizeof(int)*n);
v=(int*)malloc(sizeof(int)*n);
b=(bool*)calloc(n,sizeof(bool));
mb=(bool*)calloc(n,sizeof(bool));
for(i=0;i<n;i++)
scanf("%d",v+i);
for(i=0;i<n;i++)
scanf("%d",w+i);
mV=0;
mV=f(c,n,w,v,0,b,mb,mV);
printf("%d\n",mV);
printf("%d",mb[0]);
for(i=1;i<n;i++)
printf(" %d",mb[i]);
printf("\n");
free(w);
free(v);
free(b);
free(mb);
}
}
/*
#include<stdio.h>
#include<stdlib.h>
//c:总容量
//n:物品总个数
//w[i]:第i件物品的重量
//v[i]:第i件物品的价值
//i:当前判断要不要加入到包中的物品下标
//current:当前的存放下标标记
//maxBits:当前最优值得下标
//maxV:当前的最优值
int findMaxV(int c, int n, int *w, int *v, int i, bool *current, bool *maxBits, int maxV){
if(c<=0 || i==n){
return maxV;
}
int in,out;
current[i]=0;
out = findMaxV(c,n,w,v,i+1,current,maxBits,maxV);
if(c>w[i]){
in = findMaxV(c-w[i],n,w,v,i+1,current,maxBits,maxV)+v[i];
if(in>out){
out=in;
current[i]=1;
}
}
if(out>maxV){
for(int k=0; k<n; k++){
maxBits[i]=current[i];
}
maxV=out;
}
return maxV;
}
int main(){
int n,c,*w,*v,i,maxV;
bool *current,*maxBits;
while(scanf("%d%d",&n,&c)==2){
w=(int*)malloc(sizeof(int)*n);
v=(int*)malloc(sizeof(int)*n);
current=(bool*)calloc(n,sizeof(bool));
maxBits=(bool*)calloc(n,sizeof(bool));
for(i=0;i<n;i++){
scanf("%d",v+i);
}
for(i=0;i<n;i++){
scanf("%d",w+i);
}
maxV=0;
maxV=findMaxV(c,n,w,v,0,current,maxBits,maxV);
printf("%d\n",maxV);
printf("%d",maxBits[0]);
for(i=1;i<n;i++){
printf(" %d",maxBits[i]);
}
printf("\n");
free(w);
free(v);
free(current);
free(maxBits);
}
}
*/