1. 程式人生 > >演算法第5章作業

演算法第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; }

 

三、在本章學習過程中遇到的問題及結對程式設計的情況

 

回溯演算法有時候的約束函式會寫錯,有時候剪枝也會剪錯。