Chinaunix首页 | 论坛 | 博客
  • 博客访问: 53958
  • 博文数量: 9
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-16 22:03
个人简介

Small thing follow your head, big thing follow your heart.

文章分类

全部博文(9)

文章存档

2015年(4)

2014年(5)

我的朋友

分类: C/C++

2014-11-13 20:56:43

1.背包问题:
有n个重量和价值分别为w1, v1的物品,从这些物品中挑选出总重量不超过w的物品, 求所有挑选方案中价值总和的最大值。
(限制条件:1《n《100;1《wi,vi《 100; 1《w《10000)

方法一:(时间复杂度0(2^n))

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. #define MAX_N 100

  3. int n = 0;
  4. int w = 0;
  5. int ww[MAX_N];
  6. int v[MAX_N];

  7. int rec(int i, int j)
  8. {
  9.     int res;

  10.     if (i == n)
  11.     {
  12.         res = 0; /*没有剩余的物品*/
  13.     }
  14.     else if (j < ww[i])
  15.     {
  16.         res = rec(i + 1, j); /*无法挑选这个物品*/
  17.     }
  18.     else /*挑选和不挑选的情况都尝试*/
  19.     {
  20.         res = max(rec(i +1, j), rec(i + 1, j - ww[i]) + v[i]);
  21.     }

  22.     return res;
  23. }

  24. int max(int x, int y)
  25. {
  26.     return (x > y ? x : y);
  27. }

  28. void solve()
  29. {
  30.     printf("能取得最大价值为:%d\n", rec(0, w));
  31. }

  32. int main()
  33. {
  34.     int i = 0;

  35.     printf("请输入物品数量:\n");
  36.     scanf("%d", &n);
  37.     for(i = 0; i < n; i++)
  38.     {
  39.         printf("输入第%d个物品的重量和价值:\n", i + 1);
  40.         scanf("%d %d", &ww[i], &v[i]);
  41.     }

  42.     printf("要取物品重量:");
  43.     scanf("%d", &w);

  44.     solve();

  45.     return 0;
  46. }
运行结果:


方法2:(采用记忆化搜索,时间复杂度为O(nw))

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. #define MAX_N 100

  3. int n = 0;
  4. int w = 0;
  5. int ww[MAX_N];
  6. int v[MAX_N];
  7. int dp[MAX_N + 1][MAX_N + 1]; /*记忆数组*/

  8. int rec(int i, int j)
  9. {
  10.     int res;

  11.     /*已经搜索过了*/
  12.     if (dp[i][j] >= 0)
  13.     {
  14.         return dp[i][j];
  15.     }

  16.     if (i == n)
  17.     {
  18.         res = 0; /*没有剩余的物品*/
  19.     }
  20.     else if (j < ww[i])
  21.     {
  22.         res = rec(i + 1, j); /*无法挑选这个物品*/
  23.     }
  24.     else /*挑选和不挑选的情况都尝试*/
  25.     {
  26.         res = max(rec(i +1, j), rec(i + 1, j - ww[i]) + v[i]);
  27.     }

  28.     dp[i][j] = res; /*记忆!*/

  29.     return res;
  30. }

  31. int max(int x, int y)
  32. {
  33.     return (x > y ? x : y);
  34. }

  35. void solve()
  36. {
  37.     memset(dp, -1, sizeof(dp));
  38.     printf("能取得最大价值为:%d\n", rec(0, w));
  39. }

  40. int main()
  41. {
  42.     int i = 0;

  43.     printf("请输入物品数量:\n");
  44.     scanf("%d", &n);
  45.     for(i = 0; i < n; i++)
  46.     {
  47.         printf("输入第%d个物品的重量和价值:\n", i + 1);
  48.         scanf("%d %d", &ww[i], &v[i]);
  49.     }

  50.     printf("要取物品重量:");
  51.     scanf("%d", &w);

  52.     solve();

  53.     return 0;
  54. }



阅读(1822) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~