赞
踩
1、树形结构的应用
当需要求解的问题是从N个元素所构成的全集U中找寻满足问题条件的子集时,相应的解空间树称为子集树,在对子集树进行深度优先遍历时储存所经过边的数值,1表示包含该元素,0表示不包含改元素,当遍历到叶子节点时输出这由0与1组成且有N位的字符串,这样一来深度优先遍历完这棵树就能得到其全集U的所有子集,也是求解0-1背包问题会遇到的所有情况。
2、回溯法求解思想
我们在用深度优先搜索子集树时并不是非要遍历完每一种情况,在遍历途中利用剪枝条件可以减少代码语句执行次数,回溯法就是在搜索最优解的途中避免无效搜索的一种优化算法。
3、具体代码和现
- #include <stdio.h>
- #include <stdlib.h>
- const int N=10;
- const int bag=N*2;
- struct goods{
- int w;
- int v;
- }g[N];
- int max_value=0;
- int a[N],r[N+1],x[N];
- int huisu(int count,int now_v,int now_w);
- int main(){
- int i;
- for (i = 0; i < N; i++) {
- g[i].v = rand() % 5 + 1;
- g[i].w = rand() % 5 + 1;
- printf("物品%d,价值%d,重量%d\n", i, g[i].v, g[i].w);
- }
- r[N] = 0;
- for (i = N - 1; i >= 0; i--) {
- r[i] = r[i + 1] + g[i].v;
- }
- int maxv = huisu(0, 0, 0);
- printf("装入的物品是:\n");
- int w=0;
- for(int i=N-1;i>=0;i--){
- if(x[i]==1){
- printf("%d ",i);
- }
- }
- printf("\n能获得的最大价值为:%d", maxv);
- return 0;
- }
- int huisu(int count,int now_v,int now_w)
- {
- if(count==N){
- if(now_w<=bag&&now_v>max_value){
- max_value=now_v;
- for(int j=0;j<N;j++){
- x[j]=a[j];
- }
- }
- }
- else{
- for(int i=0;i<=1;i++){
- a[count]=i;
- now_v=now_v+g[count].v*i;
- now_w=now_w+g[count].w*i;
- if(now_w<=bag&&now_v+r[count+1]>=max_value)
- huisu(count+1,now_v,now_w);
- }
- }
- return max_value;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。