前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单背包

简单背包

作者头像
Cell
发布2022-02-25 14:19:43
2270
发布2022-02-25 14:19:43
举报
文章被收录于专栏:Cell的前端专栏

1) 问题描述:

假设有一个能装入总体积为 T 的背包和 n 件体积分别为 W1,W2,···,Wn 的物品,能否从 n 件物品中挑选若干件恰好装满背包,即使 W1+W2+···+Wn=T,要求找出所有满足上述条件的解。例如:当 T=10,共 6 件物品,物品的体积为{1,2,3,4,5,8},那么可找到下列 4 组解:(1,2,3,4)、(1,4,5)、(2,3,5)、(2、8)。

2) 实现提示:

可利用回溯法的设计思想来解决背包问题。首先,将物品排成一列,然后顺序选取物品装入背包,假设已选取了前 i 件物品之后背包还没有装满,则继续选取第 i+1 件物品,若该件物品“太大”不能装入,则丢弃而继续选取下一件,直至背包装满为止。但如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入背包的那件物品“不合适”,应将它取出“丢弃一边”,继续再从“它之后”的物品中选取,如此重复,直至求得满足条件的解,或者无解。由于回溯求解的规则是“后进先出”,因此要用到栈。

使用栈作为该程序的数据结构,利用栈进行语法检查,以深度优先的搜索方式解空间,实现递归过程和函数的调用,在设计时还使用 C 语言的数组及其循环语言来实现程序。 运用回溯法解题,在搜索解空间树时,只要其左儿子节点是一个可行结点,搜索就进入左子树,在右子树中有可能包含最优解是才进入右子树搜索。否则将右子树剪去。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

#include <stdio.h> #include <windows.h> #define size 50 struct stacks { int data[size]; int top; } stack; void backpack(int number,int V,int w[]){ int i,j=1,k=0; int flag=0; do { while (V > 0 && k <= number) { if (V >= w[k]) { stack.data[stack.top] = k;//第 k 个物品的体积下标 stack.top++; V -= w[k]; } k++; } if (V == 0) { flag=1; printf("第%d 个符合条件的解:", j); for (i = 0; i < stack.top; i++) { printf("%d ", w[stack.data[i]]); } j++; printf("\n"); } //k 满时回溯 k = stack.data[--stack.top]; stack.data[stack.top] = 0; V += w[k]; k++; } while (!(stack.top == 0 && k == number)); if(!flag){ printf("背包无解!\n"); } } void judge(int number,int V,int w[]){ int i,s = 0; for (i = 0; i < number; i++) s = s + w[i]; if(V > s){ printf("背包无解!\n"); exit(0); } if(V==s){ printf("只有一个符合条件的解:%d\n", V); exit(0); } } int main() { int w[size]; int V; int i = 0; int j = 0; int number; printf("\t **简单背包问题**\n\n"); printf("\n 请输入可供选择装入物品的个数:\n"); scanf("%d", &number); printf("\n 请输入各件物品的体积:\n"); for (i = 0; i < number; i++) scanf("%d", &w[i]); //排序 for(i=0;i<number;i++) for(j=i+1;j<number;j++) if(w[i]>w[j]){ w[i]=w[i]^w[j]; w[j]=w[i]^w[j]; w[i]=w[i]^w[j]; } printf("\n 请输入背包的总体积:\n"); scanf("%d", &V); while(V < 0){ printf("输入背包体积错误!重新输入!\n"); scanf("%d",&V); } judge(number,V,w); //初始化栈 for (i = 0; i < number; i++) stack.data[i] = 0; stack.top = 0; backpack(number,V,w); return 0; }

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1) 问题描述:
    • 2) 实现提示:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档