练习19

 
  1. /******************************************************************************
  2. 19. (背包问题) 有 N 件物品 d1,......dN,每件物品重量为 W1,..., WN
  3.  (Wi > 0), 每件物品价值为 V1,......VN (Vi>0)。用这N件物品的某个子集
  4.  填空背包,使得所取物品的总重量<=TOTAL,并设法使得背包中物品的价值尽可
  5.  能高。
  6.   输入:N件物品d1....dn,每件重量为w1...wn,每件价值v1...vn;
  7.   输出:N见物品的子集{di | 1 =< i <= n}
  8.   过程:动态规划算法(递推)
  9.   假设H[d,w]是代表含有第d件物品且总重量为w的物品总价值;得到递推式
  10.   H[d,w] = 0 其中(d=0 || w=0) 表示没有物品或重量时,总价值为0
  11.   H[d,w] = H[d-1,w] (w<wi)
  12.   H[d,w] = max{ H[d-1,w-wi]+vi , H[d-1,w] } 其中(wi=<w<=TOTAL,d>=1)
  13.  ******************************************************************************/
  14. #include <stdio.h>
  15. #include <malloc.h>
  16. #include <stdlib.h>
  17. #include <time.h>
  18. static int N; // 物品的总数
  19. static int TOTAL; // 物品的最大重量限制
  20. static int *wi; //物品重量
  21. static int *vi; //物品价值
  22. //显示数据
  23. void ShowData()
  24. {
  25.     int i;
  26.     printf("               数据              /n");
  27.     printf("---------------------------------/n");
  28.     printf("%s%10s%10s/n","序号","重量","价值");
  29.     printf("---------------------------------/n");
  30.     for(i=0; i<N; i++)
  31.         printf("%2d%10d%10d/n",i,wi[i],vi[i]);
  32.     printf("---------------------------------/n");
  33.     printf("/n");
  34. }
  35. //显示结果
  36. void ShowResult(int **P, int **S)
  37. {
  38.     int d,w = TOTAL;
  39.     printf("               结果              /n");
  40.     printf("---------------------------------/n");
  41.     printf("%s%10s%10s/n","序号","重量","价值");
  42.     printf("---------------------------------/n");
  43.     for(d=N; d>=1; d--)
  44.     {
  45.         if(S[d][w])
  46.         {
  47.             printf("%2d%10d%10d/n",d-1,wi[d-1],vi[d-1]);
  48.         }
  49.         w = P[d][w];
  50.     }
  51.     printf("---------------------------------/n");
  52.     printf("/n");
  53. }
  54. void main()
  55. {
  56.     int i;
  57.     int d,w;
  58.     int **H;
  59.     int **P;
  60.     int **S;
  61.     printf("请输入物品总数N和物品最大重量限制TOTAL:/n");
  62.     scanf("%d%d",&N,&TOTAL);
  63.     //申请空间
  64.     wi = (int*)malloc(N*sizeof(int));//重量
  65.     vi = (int*)malloc(N*sizeof(int));//价值
  66.     H = (int**)malloc((N+1)*sizeof(int*));//解价值数组
  67.     //..............................................
  68.     P = (int**)malloc((N+1)*sizeof(int*));//保存解路径
  69.     S = (int**)malloc((N+1)*sizeof(int*));//该序号的物品是否有选中
  70.     //..............................................
  71.     for(i=0; i<=N; i++)
  72.         H[i] = (int*)malloc((TOTAL+1)*sizeof(int));
  73.     //..............................................
  74.     for(i=0; i<=N; i++)
  75.         P[i] = (int*)malloc((TOTAL+1)*sizeof(int));
  76.     for(i=0; i<=N; i++)
  77.         S[i] = (int*)malloc((TOTAL+1)*sizeof(int));
  78.     //...............................................
  79.     srand(time(NULL));
  80.     for(i=0; i<N; i++)
  81.         wi[i] = rand()%(TOTAL/2)+1;
  82.     for(i=0; i<N; i++)
  83.         vi[i] = rand()%10+1;
  84.     
  85.     ShowData();
  86.     //初始化
  87.     for(d=0; d<=N; d++)
  88.     {
  89.         for(w=0; w<=TOTAL; w++)
  90.         {
  91.             if(d==0 || w==0)
  92.                 H[d][w] = 0;
  93.             else if(w<wi[d-1])
  94.             {
  95.                 H[d][w] = H[d-1][w];
  96.                 //...........................
  97.                 P[d][w] = w;
  98.                 S[d][w] = 0;
  99.                 //...........................
  100.             }
  101.             else
  102.             {
  103.                 H[d][w] = H[d-1][w-wi[d-1]]+vi[d-1];
  104.                 //.................................
  105.                 P[d][w] = w-wi[d-1];
  106.                 S[d][w] = 1;
  107.                 //.................................
  108.                 if(H[d][w] < H[d-1][w])
  109.                 {
  110.                     H[d][w] = H[d-1][w];
  111.                     //............................
  112.                     P[d][w] = w;
  113.                     S[d][w] = 0;
  114.                     //............................
  115.                 }
  116.             }
  117.         }
  118.     }
  119.     //显示结果
  120.     ShowResult(P,S);
  121.     printf("%d/n",H[d-1][w-1]);
  122.     //释放空间
  123.     free(wi);
  124.     free(vi);
  125.     for(i=0; i<=N; i++)
  126.         free(H[i]);
  127.     free(H);
  128.     for(i=0; i<=N; i++)
  129.         free(P[i]);
  130.     free(P);
  131.     for(i=0; i<=N; i++)
  132.         free(S[i]);
  133.     free(S);
  134. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值