算法第五章作业

 

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. 在本章学习过程中遇到的问题及结对编程的情况

回溯法中最难的问题就是怎么构造解空间树以及怎么写剪枝函数,在跟队友一起编程的时候大家想法和思路会不一样,不过也是个很好的交流过程。

 

posted @ 2018-12-23 14:18  winkeybobo  阅读(122)  评论(0)    收藏  举报