最大の群れの問題|バックトラッキング:条件付き01選択

       今日の「計算理論とアルゴリズムの設計」の最終試験の3つのプログラミングの質問を更新してください。テストケースのない質問は、本当に受け入れられません。私は試験中に自分の考えを共有し、最後に私が書いたセルフテストのユースケースを配りました。参考までに、エラーを指摘してください〜


03

グレード 15 開始時間 2020年6月24日水曜日15:10
ディスカウント 0.8 割引時間 2020年6月24日水曜日18:30
遅延提出が可能 番号 閉店時間 2020年6月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. 710↵
  2. 12↵
  3. 14↵
  4. 24↵
  5. 23↵
  6. 25↵
  7. 26↵
  8. 35↵
  9. 36↵
  10. 45↵
  11. 56↵
 
  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



終わり 

個人のパブリックアカウント チキンウィングプログラミング」注意を払うことを歓迎しますここには、真面目で行儀のよいコードファーマーがいます。

- ---最も行儀のブログERを行い、ほとんどの固体プログラマを行います----

それぞれの記事を注意深く書くことを目指し、通常はメモをプッシュ更新にまとめます〜

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43787043/article/details/106950655