“背包问题”的算法

时间:2023-02-12 22:34:00

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

递归算法

 

“背包问题”的算法#include  < stdio.h >
“背包问题”的算法
#define  N 7
“背包问题”的算法
#define  S 15
“背包问题”的算法“背包问题”的算法
int  w[N + 1 =   ... {0,1,2,3,4,5,6,7} ;
“背包问题”的算法
“背包问题”的算法
int  knap( int  s,  int  n)
“背包问题”的算法“背包问题”的算法
... {
“背包问题”的算法    
if(s == 0)
“背包问题”的算法        
return 1;
“背包问题”的算法    
if(s < 0 || s >0 && n < 1)
“背包问题”的算法        
return 0;
“背包问题”的算法    
if(knap(s - w[n], n-1))
“背包问题”的算法“背包问题”的算法    
...{
“背包问题”的算法        printf(
"%4d ", w[n]);
“背包问题”的算法        
return 1;
“背包问题”的算法    }

“背包问题”的算法    
return knap(s, n-1);
“背包问题”的算法}

“背包问题”的算法
void  main()
“背包问题”的算法“背包问题”的算法
... {
“背包问题”的算法    
if(knap(S, N))
“背包问题”的算法        printf(
"OK! ");
“背包问题”的算法    
else
“背包问题”的算法        printf(
"NO! ");
“背包问题”的算法    getchar();
“背包问题”的算法}

 非递归

 

“背包问题”的算法#include  < stdio.h >
“背包问题”的算法
#define  N 7
“背包问题”的算法
#define  S 15
“背包问题”的算法typedef 
struct
“背包问题”的算法“背包问题”的算法
... {
“背包问题”的算法    
int s;
“背包问题”的算法    
int n;
“背包问题”的算法    
int job;
“背包问题”的算法}
KNAPTP;
“背包问题”的算法“背包问题”的算法
int  w[N + 1 =   ... {0,1,4,3,4,5,2,7} ;
“背包问题”的算法
“背包问题”的算法
int  knap( int  s,  int  n)
“背包问题”的算法“背包问题”的算法
... {
“背包问题”的算法    KNAPTP stack[
100], x;
“背包问题”的算法    
int top, k, rep;
“背包问题”的算法    x.s 
= s; x.n = n;
“背包问题”的算法    x.job 
= 0;
“背包问题”的算法    top 
= 1; stack[top] = x;
“背包问题”的算法    k 
= 0;
“背包问题”的算法    
while(top > 0 && k == 0)
“背包问题”的算法“背包问题”的算法    
...{
“背包问题”的算法        x 
= stack[top];
“背包问题”的算法        rep 
= 1;
“背包问题”的算法        
while(!&& rep)
“背包问题”的算法“背包问题”的算法        
...{
“背包问题”的算法            
if(x.s == 0)
“背包问题”的算法                k 
= 1//caught an answer
“背包问题”的算法
            else if(x.s < 0 || x.n <= 0)
“背包问题”的算法                rep 
= 0;
“背包问题”的算法            
else
“背包问题”的算法“背包问题”的算法            
...{
“背包问题”的算法                x.s 
= x.s - w[x.n--];
“背包问题”的算法                x.job 
= 1;
“背包问题”的算法                stack[
++top] = x;
“背包问题”的算法            }

“背包问题”的算法        }

“背包问题”的算法        
if(!k) //watch rep = 0;
“背包问题”的算法“背包问题”的算法
        ...{
“背包问题”的算法            rep 
=1;
“背包问题”的算法            
while(top >= 1&& rep)
“背包问题”的算法“背包问题”的算法            
...{
“背包问题”的算法                x 
= stack[top--];
“背包问题”的算法                
if(x.job == 1)
“背包问题”的算法“背包问题”的算法                
...{
“背包问题”的算法                    x.s 
+= w[x.n + 1];
“背包问题”的算法                    x.job 
= 2//change it as discard one
“背包问题”的算法
                    stack[++top] = x;
“背包问题”的算法                    rep 
= 0;
“背包问题”的算法                }

“背包问题”的算法            }

“背包问题”的算法        }

“背包问题”的算法    }

“背包问题”的算法    
if(k) // found an answer
“背包问题”的算法“背包问题”的算法
    ...{
“背包问题”的算法        
while(top >= 1)
“背包问题”的算法“背包问题”的算法        
...{
“背包问题”的算法            x 
= stack[top--];
“背包问题”的算法            
if(x.job == 1)
“背包问题”的算法                printf(
"%d ", w[x.n + 1]);
“背包问题”的算法        }

“背包问题”的算法    }

“背包问题”的算法    
return k;
“背包问题”的算法}

“背包问题”的算法
void  main()
“背包问题”的算法“背包问题”的算法
... {
“背包问题”的算法    
if(knap(S, N))
“背包问题”的算法        printf(
"OK! ");
“背包问题”的算法    
else
“背包问题”的算法        printf(
"NO ");
“背包问题”的算法    getchar();
“背包问题”的算法}
求解部分的循环执行条件是堆栈不空且未找到解,因为当堆栈空的时候表示程序已经穷尽了所有的可能,这是使用堆栈的程序的一般特征。(利用堆栈对不在结果集中的数据进行回溯,堆栈中o的位置存放S和N,注意top的初始值是1并不是栈底),考虑数据int w[N+1] = {0,1,1,1,1,1,1,1};
堆栈不空的表达式应该是top>=1或者top>0,此处需要仔细体会stack[0]的内容和含义,否则我们很难正确构造堆栈不空的表达式;而未求得解表达式应该是k==0或者!k。