最大牛群问题 | 回溯:带条件的 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秒64M0

       此题可以考虑用回溯,枚举所有不会冲突的情况,找到最大值(其实就是一个最大团问题的模型)。由于考试时间比较紧,我没有剪枝。代码很好理解,直接上完整代码测试用例

//
// 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,做最扎实的程序员 ----

旨在用心写好每一篇文章,平常会把笔记汇总成推送更新~

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1168: 【6☆】卫星照片 内存限制:128 MB 时间限制:1.000 S 评测方式:文本比较 命题人:admin 提交:256 解决:93 题目描述 农夫john正在研究他的农场的卫星照片。照片为一个R (1 <=R <= 75) 行 C (1 <= C <= 75) 列的字符矩阵表示,如下图: .................. ..#####.......##.. ..#####......##... .................. #.......###.....#. #.....#####....... 图上的一块相连通的 "#" 表示一群奶牛或一个房间, 两个子"#" 连通的意思是说左右或上下相连.而下面的两块则是分开的: .... .#.. ..#. .... John现在根据卫星照片上的的这些“#”块的形状来判断哪些是牛群,哪些是房间.如果一个“#”块形状的边是水平或垂直的矩形,则是房间。其它的则认为都是牛群.在第一个图中,有三个房间 ( 2x1, 2x5, 1x1)和2群牛。 请根据输入文件中的数据,统计出房间数和牛群数。 数据中牛群不会包围另一个牛群或房间。 输入 第一行,两个整数: R 和 C。 2~R+1行:第 i+1 行表示照片的第 i 行情况,由 C 字符组成。 输出 第一行:房间数。 第二行:牛群数。 样例输入 复制 5 8 #####..# #####.## ......#. .###...# .###..## 样例输出 复制 2 2
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值