递归再理解

来源:互联网 发布:化工公司工艺软件 编辑:程序博客网 时间:2024/06/09 22:14

就简单的背包问题举例:
设有一个背包可以放入的物品重量为S,现有n件物品,重量分别为w1,w2,.. .,wn。问能否从这n件物品中选择若干件放入此背包,使得放入的重量之和正好为S。如果存在一种符合上述要求的选择,则称此背包问题有解,否则此问题无解,试用递归方法设计此背包问题的算法。


用递归思想解决问题,要学会把大问题化为小问题,把看似一个整体的问题细化到其中的一部,进行思考。并且要学会用“撒手”观念去解决问题。

这里写图片描述
例如背包问题的解决,首先拿到问题思考,把这个大的问题化为单个物品的小问题,则对于单个物品来说就有两种情况,一是装进背包,二是不装进背包,这样就好考虑了。
这里写图片描述
如图所示,递归的出口是当S=0,或者S<0,或者S>0且n<1;

int knapsack(int S,int n){    if(S==0) return 1;     else  if(S<0||(S>0&&n<1))  return 0;     else      {  if(knapsack(S-W[n],n-1))         {   cout<<W[n]; return 1;  }         return(knapsack(S,n-1));      }} 

这是代码,只不过N是从最大值开始的,需要不断的减。
其中的:

if(knapsack(S-W[n],n-1))         {   cout<<W[n]; return 1;  }         return(knapsack(S,n-1));

则是对递归的实现,

if(knapsack(S-W[n],n-1))         {   cout<<W[n]; return 1;  }

如果当前的物品放进去了,会出来一个结果,如果不成功,则不放进去,进行下一次的选择。此时就用到了“撒手”的观念,我不管以后的操作,knapsack(S-W[n],n-1)就是能够判断当装进这一个物品是否会成功装满。
如果最后不成功则此时就会选择不装进去。