腾讯2009年重庆笔试附加题

题目描述:有一个背包,能盛放的物品总重量为S,设有N件物品,其重量分别为w1,w2,...,wn.希望从N件物品中选择若干件物品,所选物品的重量之和恰能放入该背包,即所选物品的重量之和等于S。
    要求:用非递归的方法。
  
    便于理解,先说说递归算法。
    非常简单: 
 
 int process(int s,int n) 
    

    
if(s==0)return 1
    
if(s<0||(s>0&&n<1))return 0
    
if(process(s-w[n],n-1))   
   

        cout
<<w[n]; 
        
return 1
    }
 
    
return process(s,n-1);     
   }
 


方法1:模拟堆栈

也很简单,先定义一个struct Node
typedef struct
    
int s; 
    
int n; 
    
int job;  //1表示要,2表示不要 
    }
Node; 


然后将递归的方法用数组模拟出来,其实就是用数组实现进栈出栈。
int Process(int s,int n) 

    STACK stack[
100],x; 
    
int top,k,rep;   
    x.s
=s; 
    x.n
=n; 
    x.job
=0
    top
=1
    stack[top]
=x; 
    k
=0
    
while(k==0&&top>0)
        x
=stack[top]; 
        rep
=1
        
while(!k&&rep)
            
if(x.s==0)k=1
            
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){                     //总重量超出,需要丢弃其中的某个物品 
                rep=1
                
while(top>=1&&rep)
                    x
=stack[top--]; 
                    
if(x.job==1)
                        x.s
+=w[x.n+1];  //丢弃物品 
                        x.job=2
                        stack[
++top]=x;   //出栈 
                        rep=0
                        }
 
                    }
 
                }
 
        }
 
        
if(k)
            
while(top>=1)
                x
=stack[top--]; 
                
if(x.job==1)cout<<w[x.n+1]; 
                }
 
            }
 
            
return k; 
    }
 

这个程序算法不复杂,但是由于平时这种方法用得少,尤其是stack[top--] stack[++top]这种形式的东东容易搞错,所以考试的时候我只写了算法描述。
    
方法二: 注意到题目并没有限制算法的时间空间,我们用最暴力来解决:穷举法

#include <iostream> 
using namespace std; 
void main() 

int i,j; 
int n,s;//n为物品件数,s为背包容量 
cin>>n; 
//n = 10; 
int *= new int[n+1];//存储物品大小 
int *= new int[n+1];//物品是否被选中 
for(i=1;i<=n;i++

  cin
>>w[i];//输入物品大小 
  y[i]=0
}
 
cin
>>s; 
//s = 21; 
int t=0
int flag=0
while(1

  
for(i=1;i<=n;i++)//把物品选中的整个串当作一个二进数,进行范围的全搜索 
  
   
if(y[i]==0
   

    y[i]
=1
    
//cout<<"step in y[i]=0"; 
    break
   }
 
   
else 
   

    
if (i==n) 
    

     flag 
= 1
    }
 
    y[i]
=0
    
continue
   }
 
  }
 
  t 
= 0
  
for(j=1;j<=n;j++
  

   t 
= t+w[j]*y[j]; 
  }
 
  
if(t == s)//判断是否求得解,求到解就直接退出 
  
   
for(i=1;i<=n;i++
   

    
if(y[i]==1) cout<<w[i]<<"  "
   }
 
   
break
  }
 
  
if(flag == 1//无解处理 
  
   cout
<<"no answer"<<endl; 
   
break
  }
 
}
 
}

posted on 2008-10-23 19:28 流牛ζ木马 阅读(2122) 评论(3)  编辑 收藏 引用

评论

# re: 腾讯2009年重庆笔试附加题 2008-12-05 13:58 goldallen

非常不错的 :)  回复  更多评论   

# re: 腾讯2009年重庆笔试附加题 2008-12-05 18:43 goldallen

用数组实现递归 感觉有些难度...
  回复  更多评论   

# re: 腾讯2009年重庆笔试附加题[未登录] 2009-06-01 00:13 lyx

第一个递归算法必须要保证刚刚好能装满背包,否则就会死循环了。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2007年11月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

导航

统计

公告

MY Email/MSN :mars1021@163.com QQ : 27402040 流牛ζ木马

常用链接

留言簿(6)

随笔档案

相册

搜索

最新随笔

最新评论

阅读排行榜

评论排行榜