比赛描述
试设计一个用回溯法搜索子集空间树的函数。该函数的参数包括结点可行性判定函数和上界函数等必要的函数,并将此函数用于解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); } } */