动态规划求0-1背包问题
1.问题描述如下:
经过分析后算法如下:v(i,j)表示前j个物品中能够放入承重量为j的包中的最大价值。。。。
2.具体的代码实现如下:
其中2.txt中的具体数据为:
代码:
View Code
1 #include<stdio.h> 2 #include<stdlib.h> 3 void maxValue(int *,int *,int **,int,int); 4 int ziji(int *,int *,int *,int **,int,int); 5 int max(int,int); 6 void main() 7 { 8 int i,k,num,weight; 9 FILE *p; 10 p=fopen("2.txt","r"); 11 if(p==NULL) 12 { 13 printf("文件打开失败!"); 14 exit(1); 15 } 16 fscanf(p,"%d%d",&num,&weight); 17 int *w=(int*)malloc(sizeof(int)*num); 18 int *v=(int*)malloc(sizeof(int)*num); 19 int *path=(int*)malloc(sizeof(int)*num); 20 int **vv=(int **)malloc(sizeof(int *)*(num+1)); 21 for(i=0;i<num+1;i++) 22 vv[i]=(int *)malloc(sizeof(int)*(weight+1)); 23 for(i=1;i<=num;i++) 24 fscanf(p,"%d",&w[i]); 25 for(i=1;i<=num;i++) 26 fscanf(p,"%d",&v[i]); 27 28 /*printf("%d %d\n",num,weight); 29 for(i=0;i<num;i++) 30 printf("%d\n",w[i]); 31 for(i=0;i<num;i++) 32 printf("%d\n",v[i]);*/ 33 maxValue(w,v,vv,num,weight); 34 printf("最终最大价值为: %d\n",vv[num][weight]); 35 k=ziji(w,v,path,vv,num,weight); 36 printf("最优子集为: \n"); 37 for(i=0;i<k;i++) 38 printf("%d ",path[i]); 39 } 40 //求最终最大的价值 41 void maxValue(int *w,int *v,int **vv,int num,int weight) 42 { 43 int i,j,k; 44 for(i=0;i<=num;i++) 45 vv[i][0]=0; 46 for(i=0;i<=weight;i++) 47 vv[0][i]=0; 48 for(i=1;i<=num;i++) 49 for(j=1;j<=weight;j++) 50 { 51 if(j>=w[i]) 52 { 53 k=j-w[i]; 54 vv[i][j]=max((v[i]+vv[i-1][k]),vv[i-1][j]); 55 } 56 else 57 vv[i][j]=vv[i-1][j];//谢谢楼下的提醒,此处已更正。。 58 } 59 } 60 //求最优子集 61 int ziji(int *w,int *v,int *path,int **vv,int num,int weight) 62 { 63 int i,j=5,k=0; 64 for(i=num;i>0;i--) 65 { 66 if(j>0) 67 { 68 if(vv[i][j]!=vv[i-1][j]) 69 { 70 path[k++]=i; 71 j=j-w[i]; 72 } 73 } 74 } 75 return k; 76 } 77 int max(int x,int y) 78 { 79 if(x>y) return x; 80 else return y; 81 }
附:
另外附两幅网上找到的ppt,以便于理解,参考:http://wenku.baidu.com/view/b9e4f70416fc700abb68fce0.html
(1)最大价值v(4,5)
(2)回溯法找到最优子集