数据结构-栈应用(简单背包问题)

简单背包问题:

 有一个背包,能盛放的物品总重量为s,设有n件物品,其重量分别为w1,w2,...,wn.希望从N件物品中选择若干件物品,所选物品的重量之和恰能放入该背包,即所选物品的重量之和等于s。

 

递归算法:

 1 // 背包问题-递归.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 int w[5= {14457};
 6 int knap(int s, int n)
 7 {
 8     if(s == 0)
 9     {
10         return(1);
11     }
12     else
13     {
14         if( s < 0 || (s > 0 && n < 1))
15         {
16             return(0);
17         }
18         else
19             if(knap(s - w[n - 1],n - 1== 1)
20             {
21                 printf("result: n = %d, w[%d] = %d \n", n , n - 1, w[n-1]);
22                 return (1);
23             }
24             else
25             {
26                 return(knap(s, n - 1));
27             }
28 
29     }
30 }
31 
32 int _tmain(int argc, _TCHAR* argv[])
33 {
34     knap(105);
35     return 0;
36 }

运行结果: 

 result: n = 1, w[0] = 1

result: n = 3, w[2] = 4 

result: n = 4, w[3] = 5 

非递归算法:(参考 http://blog.csdn.net/alex197963/archive/2007/05/11/1604462.aspx)

  1 #include "stdafx.h"

 2 #include <stdio.h>
 3 #define N 7
 4 #define S 15
 5 
 6 typedef struct 
 7 {
 8     int s;                                                    /*s表示考查过(就是装入)该物品后,背包所能盛放的物品的重量*/
 9     int n;                                                    /*n表示待考查的下一个物品在数组w中的下标*/
10     int job;                                                 /*job表示当前物品的状态*/                          
11 } KNAPTP;             
12 int w[N+1= {0,1,4,3,4,5,2,7};                                 /*w表示待考查 一组物品的重量,当然现实中没有重量为0的物体*/
13  
14 int knap(int s,int n)                                        /*求出一组物品的解并在屏幕上打印它们*/                                
15 {
16     KNAPTP stack[100],x;                                    /*定义一个stack数组(用于保存已查过的物品)及x,其数据类型为typedef*/
17     int top, k;                                                /*top是stack栈顶标志;k为是否求得解的标志;rep也是标志变量,意义见下面*/
18     x.s = s; x.n = n;                                        /*对工作节点x的s、n分量分别付初值*/
19     x.job = 0;                                                 /*x.job分量为0表示开始背包中没有放入任何物品,赋初值*/
20     top = 1; stack[top] = x;                                /*置top标志为1,将x节点压入stack栈*/
21     k = 0;                                                    /*k也赋初值,当然这时候没有解*/
22     while ( top>0 && k == 0 )                                /*考查各个物品i的选择情况*/
23     { 
24         x = stack[top];                                        /*从栈顶取出物品,放入工作节点x*/
25                                                             /*rep表示是否继续,赋初值1表示继续进行*/                                   
26         while ( !k)                                            /*当k等于0且rep为1时继续循环*/
27         { 
28             if(x.s==0)
29                 k=1;                                        /*x.s为0表示如果背包所能盛放的物品的重量为0(即装满),则已求得一组解*/
30             else 
31                 if (x.s<0||x.n<=0
32                     break;                                      /*否则当x.s小于0或x.n小于等于0,则rep为0,表示停止动作*/
33                  else 
34                  {
35                      x.s=x.s-w[x.n--]; 
36                      x.job=1;                                 /*否则将背包的可承重量减去选中的当前物品重量,同时选择下个物品(n--),x.job置为1表示当前物品可以放入*/
37                      stack[++top]= x;                         /*stack的top标志加1,并将工作节点(选中的下个物品)x放入栈顶*/
38                  }
39         }
40         if ( !k )                                             /*如果k等于0,暗含rep此时为0,就是处理所考查的物品不满足放入背包的条件时的情况*/                  
41         {                            
42             while (top>=1)          
43             { 
44                 x = stack[top--];                             /*将栈顶物品放入工作节点x*/
45                 if(x.job==1)                                 /*如果该物品的job状态等于1,这时也一定为1*/
46                 {
47                     x.s+=w[x.n+1];                             /*将x工作节点s分量即当前背包的可承载重量恢复,即将(上一个)不满足条件的物品的重量加回去*/
48                     x.job=2;                                       /*置x的job分量为2,表示该物品不能放入背包,在以后的选择中将不考虑该物品*/
49                     stack[++top] = x;                         /*将x压入栈顶*/
50                     break;
51                 }
52             } 
53         } 
54     } 
55     if (k)
56     {                                                        /*输出一组解*/ 
57         while (top>=1)
58         {
59             x =stack [top--];
60             if ( x.job==1 )
61                 printf ("%d ",w[x.n+1] ); /*一定要下标加1*/
62         } 
63     } 
64     return k;
65 }
66 void main()
67 
68     if (!knap(S,N)) 
69         printf("\n无解"); 
70           
71 }
posted @ 2009-05-27 17:46  Ypeng  阅读(8766)  评论(0编辑  收藏  举报