算法第五章作业
1. 对回溯算法的理解:
回溯法是一种以深度优先方式系统搜索问题解的算法。首先针对问题构造一棵解空间树,按深度优先策略,从根节点出发搜索解空间树。算法搜索至解空间树的任一结点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先策略搜索。
2. “子集和”问题的解空间结构和约束函数
解空间:构造一个二叉树,每一层代表是否选择第n个数,左子树代表选择,右子树代表不选择。
约束函数:if(sum+s[x]<=c)
具体代码:
#include <iostream>
#define MAX 10000
using namespace std;
int n,c;
int s[MAX];
int sum=0;
int vis[MAX];
int rest=0; //当前元素到最后一个元素的总和
bool backtrack(int x){
if(sum==c)
return true;
if (x>n)
return false;
rest-=s[x];
if(sum+s[x]<=c)
{
sum+=s[x];
vis[x]=1;
if ( backtrack(x+1) )
return true;
sum-=s[x];//回溯时要还原
}
if( sum + rest >= c) //在子集树中表示走右分支
{
vis[x]=0;
if ( backtrack(x+1) )
return true;
}
rest+=s[x];
return false;
}
int main()
{
cin>>n>>c;
for(int i=1;i<=n;i++){
cin>>s[i];
rest+=s[i];
}
backtrack(1);
if(!backtrack(1)) cout<<"No Solution!"<<endl;
else{
for(int i=1;i<=n;i++){
if(vis[i])
cout<<s[i]<<" ";
}
}
return 0;
}
3. 在本章学习过程中遇到的问题及结对编程的情况
回溯法中最难的问题就是怎么构造解空间树以及怎么写剪枝函数,在跟队友一起编程的时候大家想法和思路会不一样,不过也是个很好的交流过程。
浙公网安备 33010602011771号