腾讯2008年笔试题-背包问题 递归和非递归解法

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

1、递归算法

#include <iostream> #include <stdlib.h> using namespace std; const int N=7; const int S=20; int w[N+1]={0,1,4,3,4,5,2,7}; typedef struct { int s; int n; int job; }KNAPTP; 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(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; } int main(int argc, char *argv[]) { if(knap(S,N))cout<<endl<<"OK"<<endl; else cout<<"NO"<<endl; system("PAUSE"); return 0; }   

2、非递归算法

#include <iostream> #include <algorithm> #include <vector> #include <string> using namespace std; const int maxsize=100; int n,S; bool visit[maxsize]; int w[maxsize]; int q[maxsize]; int beibao() { int top=-1,begin=0,sum=0; int i; while(top!=-2) { for(i=begin;i<n;i++) { if(!visit[i] && w[i]+sum<=S) { sum+=w[i]; q[++top]=i; begin=0; visit[i]=1; if(sum==S) return top; break; } } if(i==n) { visit[q[top]]=0; sum-=w[q[top]]; begin=q[top]+1; top--; } } } int main() { cin>>n>>S; for(int i=0;i<n;i++) { cin>>w[i]; visit[i]=0; } int t=beibao(); if(t!=-1) { for(int i=0;i<=t;i++) cout<<w[q[i]]<<" "; cout<<endl; } else cout<<-1<<endl; }

3、另一个非递归解法(http://www.cppblog.com/baby-fly/archive/2009/10/24/99356.html)

#include <iostream> #include <stdlib.h> using namespace std; const int N=7; const int S=20; int w[N+1]={0,1,4,3,4,5,2,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)) { cout<<w[n]; return 1; } return knap(s,n-1); } int main(int argc, char *argv[]) { if(knap(S,N))cout<<endl<<"OK"<<endl; else cout<<"NO"<<endl; system("PAUSE"); return 0; }

你可能感兴趣的:(腾讯2008年笔试题-背包问题 递归和非递归解法)