最大牛羣問題 | 回溯:帶條件的 01 選擇

       更新一下今天 “計算理論與算法設計” 期末考試的三道編程題,沒有測試用例的題真是太藍受了。分享一下我考試時的思路,最後也給出了我編寫的自測用例。僅供參考,如有錯誤還請指出~


03

成績 15 開啓時間 2020年06月24日 星期三 15:10
折扣 0.8 折扣時間 2020年06月24日 星期三 18:30
允許遲交 關閉時間 2020年06月24日 星期三 18:30

題目描述:

    農場主決定把奶牛帶到位置較遠新的草場,爲了提高效率,他有如下考慮:1)帶儘可能多的牛過去;2)有些牛在一起趕路時可能相互打架影響速度,這樣的牛不能一起走,所以每組這樣的奶牛,最多隻能帶一頭。你的任務是幫農場主確定最多帶多少奶牛去新草場。

輸入格式:

第1行有2個正整數n(0<n<20)和m(0<m<160),分別表示奶牛的數目和不能一起走的奶牛組的數目。奶牛編號爲1,2,…,n。

接下來的m行中,每行有2個正整數i和j,表示i與j不能一起走(i<j)。

輸出格式:

輸出一行,要帶走牛的最大數目。

 

  測試輸入 期待的輸出 時間限制 內存限制 額外進程
測試用例 1  
  1. 7 10↵
  2. 1 2↵
  3. 1 4↵
  4. 2 4↵
  5. 2 3↵
  6. 2 5↵
  7. 2 6↵
  8. 3 5↵
  9. 3 6↵
  10. 4 5↵
  11. 5 6↵
 
  1. 3↵
1秒 64M 0

       此題可以考慮用回溯,枚舉所有不會衝突的情況,找到最大值(其實就是一個最大團問題的模型)。由於考試時間比較緊,我沒有剪枝。代碼很好理解,直接上完整代碼測試用例

//
// Created by A on 2020/6/24.
//

#include <cstdio>
#include <algorithm>

#define MAXN 25
using namespace std;

int n, m;
bool match[MAXN][MAXN]; //false即不匹配
bool choose[MAXN] = {false};   //記錄是否選擇了此牛
int cur = 0, ans = 0;

/* 處理輸入 */
void Init() {
    scanf("%d %d", &n, &m);

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            match[i][j] = true;
    int p, q;
    for (int i = 1; i <= m; i++) {
        scanf("%d %d", &p, &q);
        match[p][q] = match[q][p] = false;
    }
}

/* 判斷第 x 頭牛是否可以加入 */
bool IsValid(int x) {
    for(int i = 1; i < x; i++)
        if(choose[i] && !match[i][x])  //如果選擇了第 i 頭牛且不與本頭牛匹配
            return false;
    return true;
}

void backtrack(int step) {
    bool flag = false;

    /* 回溯的終點 */
    if (step > n) {
        ans = max(cur, ans);
        return;
    }
    //如果可以加入,就考慮加入
    if(IsValid(step)) {
        flag = true;
        cur++;
        choose[step] = true;
        backtrack(step + 1);
    }
    //如果之前加入過,之後要考慮不加入的情況,需要恢復數據
    if(flag) {
        choose[step] = false;
        cur--;
    }
    //考慮不加入
    backtrack(step + 1);
}

int main() {
    Init();
    backtrack(1);
    printf("%d\n", ans);
}

測試用例:

7 10
1 2
1 4
2 4
2 3
2 5
2 6
3 5
3 6
4 5
5 6
輸出:3


7 3
1 2
1 4
2 4
輸出:5


10 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
輸出:5


3 1
1 2
輸出:2


5 3
1 2
3 4
4 1
輸出:3


7 7
3 6
7 1
1 6
1 2
2 3
2 6
6 4
輸出:4


8 10
7 8
1 6
3 5
4 5
6 7
3 1
1 4
2 7
1 2
3 6
輸出:4



end 

歡迎關注個人公衆號 雞翅編程 ”,這裏是認真且乖巧的碼農一枚。

---- 做最乖巧的博客er,做最紮實的程序員 ----

旨在用心寫好每一篇文章,平常會把筆記彙總成推送更新~

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章