免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1954 | 回复: 9

[算法] 0-1 背包,请问中间结果怎么缓存,结果集怎么获取? [复制链接]

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-08-20 17:44 |显示全部楼层
本帖最后由 lxyscls 于 2015-08-21 17:27 编辑
  1. #include <string.h>
  2. #include <stdio.h>

  3. typedef struct {
  4.         int v; // value
  5.         int w; // weight
  6. } X;

  7. X x[] = { {20, 2}, {25, 3}, {30, 4}, {40, 5}, {50, 6}};

  8. #define N 5
  9. int n = N;

  10. int bp_size(unsigned bitmap)
  11. {
  12.         int i, j = 0;

  13.         for (i = 0; i < n; i++)
  14.                 if (bitmap & (1 << i))
  15.                         ++j;

  16.         return j;
  17. }

  18. int max_r(unsigned bp, int W)
  19. {
  20.         int i;
  21.         int tmp = 0;
  22.         int max = 0;

  23.         if (!bp_size(bp))
  24.                 return 0;
  25.        
  26.         for (i = 0; i < n; i++) {
  27.                 if (bp & (1 << i) && x[i].w <= W) {
  28.                         tmp = x[i].v + max_r(bp & (~(1 << i)), W - x[i].w);
  29.                         if (max == 0 || max < tmp) {
  30.                                 max = tmp;
  31.                         }
  32.                 }
  33.         }

  34.         return max;
  35. }

  36. int main(void)
  37. {
  38.         int i;
  39.         unsigned bp = 0x1f;

  40.         i = max_r(bp, 10);

  41.         printf("%d\n", i);

  42.         return 0;
  43. }
复制代码
0-1背包,请问中间结果怎么存呢?另外就是结果集怎么存,怎么知道最终结果是哪些组成的?

好像跟一般的动态规划不太一样哦,通常的是i<k<j,左右分开,用["i"][j]矩阵就存下来了,递归就可以了

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-08-20 18:01 |显示全部楼层
本帖最后由 lxyscls 于 2015-08-20 18:01 编辑

找到一个 http://www.cnblogs.com/shuaiwhu/archive/2012/05/18/2504175.html,但是不是递归
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. //每件物品的价值和重量
  4. typedef struct goods_t
  5. {
  6.   int weight;
  7.   int value;
  8. }goods;

  9. //动态规划
  10. int dp(goods* data, const int n, const int weight)
  11. {
  12.   int A[n+1][weight+1];
  13.   int i;
  14.   //如果i=0或者w=0
  15.   for (i = 0; i < n+1; i++)
  16.     A[i][0] = 0;
  17.   for (i = 0; i < weight+1; i++)
  18.     A[0][i] = 0;
  19.   int w;
  20.   for (i = 1; i <= n; i++)
  21.   {
  22.     for (w = 1; w <= weight; w++)
  23.     {
  24.       if (data[i-1].weight > w)
  25.     A[i][w] = A[i-1][w];
  26.       else
  27.       {
  28.     A[i][w] = A[i-1][w] > (data[i-1].value + A[i-1][w-data[i-1].weight]) ? A[i-1][w] : (data[i-1].value + A[i-1][w-data[i-1].weight]);
  29.       }
  30.     }
  31.   }
  32.   return A[n][weight];
  33. }

  34. int main()
  35. {
  36.   //输入最大重量
  37.   int max_weight;
  38.   scanf("%d", &max_weight);
  39.   //输入物品件数及其重量和价值
  40.   int num;
  41.   scanf("%d", &num);
  42.   int n = num;
  43.   goods* data = (goods*)malloc(n*sizeof(goods));

  44.   goods g;
  45.   while (num--)
  46.   {
  47.     scanf("%d%d", &(g.weight), &(g.value));
  48.     data[n-num-1] = g;
  49.   }
  50.   printf("%d\n", dp(data, n, max_weight));
  51.   return 0;
  52. }
复制代码

论坛徽章:
35
双子座
日期:2014-05-09 17:56:38程序设计版块每日发帖之星
日期:2015-08-30 06:20:00程序设计版块每日发帖之星
日期:2015-12-24 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-27 11:07:07程序设计版块每日发帖之星
日期:2016-01-12 06:20:0015-16赛季CBA联赛之北京
日期:2016-01-15 01:01:2115-16赛季CBA联赛之浙江
日期:2016-01-15 22:38:20程序设计版块每日发帖之星
日期:2016-01-18 06:20:00每日论坛发贴之星
日期:2016-01-18 06:20:0015-16赛季CBA联赛之北控
日期:2016-01-30 21:43:01程序设计版块每日发帖之星
日期:2016-02-08 06:20:0015-16赛季CBA联赛之山西
日期:2016-02-20 10:54:41
发表于 2015-08-20 18:44 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-08-20 23:03 |显示全部楼层
本帖最后由 lxyscls 于 2015-08-21 18:12 编辑

一L我选择了很蠢的递归方式

二L的应该可以改成递归方式

论坛徽章:
11
巨蟹座
日期:2013-12-23 11:12:14双子座
日期:2014-08-28 09:14:55子鼠
日期:2014-07-25 16:21:22摩羯座
日期:2014-07-23 15:17:47摩羯座
日期:2014-05-30 13:09:05午马
日期:2014-04-30 18:10:00天秤座
日期:2014-04-25 12:12:00申猴
日期:2014-04-22 11:30:15午马
日期:2014-03-07 16:06:40辰龙
日期:2013-12-25 18:36:00摩羯座
日期:2014-09-02 17:00:55
发表于 2015-08-21 13:18 |显示全部楼层

论坛徽章:
11
巨蟹座
日期:2013-12-23 11:12:14双子座
日期:2014-08-28 09:14:55子鼠
日期:2014-07-25 16:21:22摩羯座
日期:2014-07-23 15:17:47摩羯座
日期:2014-05-30 13:09:05午马
日期:2014-04-30 18:10:00天秤座
日期:2014-04-25 12:12:00申猴
日期:2014-04-22 11:30:15午马
日期:2014-03-07 16:06:40辰龙
日期:2013-12-25 18:36:00摩羯座
日期:2014-09-02 17:00:55
发表于 2015-08-21 13:22 |显示全部楼层
有点难,你得明白什么是DP,第i项和第i+1项是有关系的,同理i-1项和i项也是有关系的,....倒推回去第一项(这个逻辑具体怎么写得看你对他的理解了),记录这个数组,然后再反转...

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-08-21 18:06 |显示全部楼层
回复 6# Susake_


    请问什么是DP?
  1. #include <string.h>
  2. #include <stdio.h>

  3. typedef struct {
  4.         int v; // value
  5.         int w; // weight
  6. } X;

  7. X x[] = { {20, 2}, {25, 3}, {30, 4}, {40, 5}, {50, 6}};

  8. #define N 5
  9. #define W 10

  10. int r[N+1][W+1]; // choice record
  11. int m[N+1][W+1]; // middle result

  12. void max_r(int n, int w)
  13. {
  14.         if (m[n][w] != -1)
  15.                 return;

  16.         if (n == 0 || w == 0) {
  17.                 m[n][w] = 0;
  18.                 return;
  19.         }

  20.         if (x[n-1].w > w) {
  21.                 max_r(n-1, w);
  22.                 m[n][w] = m[n-1][w];
  23.                 r[n][w] = n - 1;
  24.         } else {
  25.                 max_r(n-1, w);
  26.                 max_r(n-1, w - x[n-1].w);

  27.                 if (m[n-1][w] > x[n-1].v + m[n-1][w-x[n-1].w]) {
  28.                         m[n][w] = m[n-1][w];
  29.                         r[n][w] = n - 1;
  30.                 } else {
  31.                         m[n][w] = x[n-1].v + m[n-1][w-x[n-1].w];
  32.                         r[n][w] = n;
  33.                 }
  34.         }
  35. }

  36. void print_r(int n, int w)
  37. {
  38.         if (n == 0 || w == 0)
  39.                 return;

  40.         if (r[n][w] == n) {
  41.                 printf("%d\n", n - 1);
  42.                 print_r(n-1, w-x[n-1].w);
  43.         } else {
  44.                 print_r(n-1, w);
  45.         }
  46. }

  47. int main(void)
  48. {
  49.         memset(m, -1, sizeof(m));
  50.         memset(r, -1, sizeof(r));

  51.         max_r(N, W);

  52.         printf("%d\n", m[N][W]);

  53.         print_r(N, W);

  54.         return 0;
  55. }
复制代码

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-08-21 18:10 |显示全部楼层
回复 3# __BlueGuy_


    递归可以缓存,见7L
    这个问题奇葩就奇葩在,中间结果需要存储在一个 (n + 1 * w + 1)的矩阵里面,中间选择也存储在这样一个矩阵里面
    之前接触的问题,都是存储在一个(n+1 * n+1)的矩阵里面,打死都想不出

论坛徽章:
1
2015亚冠之阿尔艾因
日期:2015-08-24 15:46:57
发表于 2015-08-24 10:48 |显示全部楼层
DP是动态规划

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2015-08-24 11:12 |显示全部楼层
我晕,缩写害死人啊

我后面用的递归应该就是动态规划了吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP