算法第5章作业

一、对回溯算法的理解

根据给定的要求进行递归的计算。

每一次的递归,符合给出的特定条件时,暂时保存当前的状态,进入下一层的计算;否则,退出当层的计算,并根据是否有返回值来决定是否更新上一层的状态。

也就是说,回溯算法一定要给出限界函数,不然会一直递归下去,最后爆栈。

 

二、“子集和”问题的解空间结构和约束函数

 

1、解空间

 

二维数组

 

2、约束函数

 

if(s > k){
    --t;
    return ;
}

假如上一层的选择的和与当前层的数相加大于目标,就不选择。

 

3、代码

#include <iostream>
using namespace std;

int n, k;
int sum = 0, t = 0;
bool is = false;
int num[10005], ans[10005];

void dfs(int s, int x){
    s += num[x];
    ans[t++] = num[x];
    if(s == k){
        is = true;
        return ;
    }
    else if(s > k){
        --t;
        return ;
    }
    else {
        for(int i = x+1; i <= n; ++i){
            dfs(s, i);
            if(is){
                return ;
            }
        }
    }
    --t;
    return ;
}

int main(){
    scanf("%d %d", &n, &k);
    for(int i = 1; i <= n; ++i){
        scanf("%d", &num[i]);
        sum += num[i];
    }
    if(sum < k){
        printf("No Solution!");
    }
    else{
        for(int i = 1; i <= n; ++i){
            dfs(0, i);
            if(is){
                for(int j = 0; j < t; ++j){
                    printf("%d ", ans[j]);
                }
                break;
            }
        }
        
        if(!is){
            printf("No Solution!");
        }
    }
    return 0;
} 

 

三、在本章学习过程中遇到的问题及结对编程的情况

 

回溯算法有时候的约束函数会写错,有时候剪枝也会剪错。

猜你喜欢

转载自www.cnblogs.com/MiNGLuvU/p/10139745.html
今日推荐