第五章作业

你对回溯算法的理解

    回溯法,通过深度优先策略,从根结点搜索一个问题的所有解得出答案。回溯法在求问题的解时,要回溯到根,且把所有子树都搜索遍才会结束,当然有些子树不满足条件什么的,就被“剪枝”剪掉了。

请说明“子集和”问题的解空间结构和约束函数

#include<iostream>
using namespace std;
int flag=0;
int m=10000;
void backtrack(int a[],int n,int c,int x[],int i,int sum,int left){
    if(flag==1)
        return;
    if(i==n||left==0){
        if(sum==c){
            flag=1;
            for(int j=0;j<n;j++){
                if(x[j]==0)
                    continue;
                else
                    cout<<x[j]<<" ";
            }
        }
        return ;
    }
    if(sum+a[i]<=c){
    //    cout<<"我进去了"<<endl;
        sum+=a[i];
    //    cout<<sum<<"  sum"<<endl;
        left=c-sum;
    //    cout<<left<<" left"<<endl;
        x[i]=a[i];
    //    cout<<x[i]<<"  x[i]"<<endl;
        backtrack(a,n,c,x,i+1,sum,left);
    //cout<<"我出去了"<<endl;
        x[i]=0;
    //    cout<<x[i]<<"  x[i]"<<endl;
        sum-=a[i];
    //    cout<<sum<<"  sum"<<endl;
        left=c-sum;
    }
    if(left>=m){
        backtrack(a,n,c,x,i+1,sum,left);
    //    cout<<"我进入else了"<<endl;
    }
}
int main(){
    int n,c;
    cin>>n>>c;
    int a[n];
    int sum=0;
    for(int i=0;i<n;i++){
        cin>>a[i];
        sum+=a[i];
        if(m>a[i])
            m=a[i];
    }
//    cout<<"m: "<<m<<endl;
//    sort(a,a+n);
    int x[n];
    for(int i=0;i<n;i++)
        x[i]=0;
    if(sum<c||c<m){
        cout<<"No Solution!";
        return 0;
    }
    else
        backtrack(a,n,c,x,0,0,c);
    if(flag==0)
        cout<<"No Solution!";
    return 0;
}
View Code

    解空间其实质就是判断每一个数字是否放入目的数组,与0-1背包问题相似。

    约束函数则是:判断当前的left是否比源数组的最小数还小;每一次要加入某一数据时判断是否比目标值大;判断是否已经扫描完源数组。 

请说明在本章学习过程中遇到的问题及结对编程的情况

    回溯遇到的问题,主要是for循环+递归这段有点绕,在N后问题、和本次作业第二题都用了这种方式求解,要捋清楚思路有点困难。

posted @ 2018-12-22 22:07  GYRY  阅读(117)  评论(0编辑  收藏  举报