• 动态规划求01背包问题


    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)回溯法找到最优子集

  • 相关阅读:
    java中商业数据计算时用到的类BigDecimal和DecimalFormat
    Git和SVN之间的区别
    ubuntu 交叉编译arm linux 内核小例子
    交叉编译工具链介绍《Building Embedded Linux Systems》
    交叉编译工具链命名详解
    oracle数据库分页总结
    oracle随机数(转)
    oracle函数nvl, nvl2, nullif
    反转数字, 即输入123, 返回321
    java试题
  • 原文地址:https://www.cnblogs.com/lpshou/p/2454009.html
Copyright © 2020-2023  润新知