动态规划求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)回溯法找到最优子集

 

posted @ 2012-04-17 17:16  lpshou  阅读(6010)  评论(7编辑  收藏  举报