数据结构与算法笔记:计算思维之人鬼渡河问题

离散数学:过河问题 过河问题(一)图论方法 农夫过河问题 问题描述 一个农夫带着一头狼、一头羊、一颗白菜过河。他面前只有一条船,只能容纳他和一件物品,只有农夫会划船。如果农夫不在场,狼会吃羊、羊会吃白菜,农夫在场则不会。求将所有物品运到对岸的方案。 解题思路 根据物品的位置定义状态,若在左岸记为1,右岸记为0,于是最终方案就是(1,1,1,1)-->(0,0,0,0)所经过的路径。 1、定义状态 2、列举所有状态(人、狼、羊、菜) 3、删除不合理的状态(狼和羊、羊和菜) 4、连边(模拟一次渡 阅读详情

人鬼渡河问题

1 ) 问题描述

  • 目标:将东岸的3人3鬼通过一只小船安全转移到西岸,希望摆渡次数尽可能少
  • 条件
    • 船的容量有限,一次最多只能坐2人(或2鬼或1人1鬼)
    • 无论是在河的东岸还是在河的西岸,一旦鬼数多于人数,则人将被鬼吃掉
    • 怎样渡河的大权掌握在人的手中
  • 说明:划船的时间忽略不计。船一靠岸即将船与岸视为一体,人和鬼即使还没有下 船也视为已上岸
  • 任务:编写程序,求出一种渡河方案

在这里插入图片描述

2 ) 分析

  • 目标是找到一种策略,能将人鬼安全摆渡至对岸。这里的方案: 一系列“指令”。
  • 计算机擅长做计算的问题,也就是说指令必须是对数的运算(将一个数转变为另一个数)
  • 对于上面的渡河问题让计算机来处理必须将他们转化成数学领域可以计算的东西,也就是我们必须要建立一种数学模型
  • 所以,在确定指令之前,应该确定是哪些数需要被计算,它们是什么?
  • 我们需要考察变化的量,我们需要分析什么东西在变
    • 船的方向
    • 船里面的乘客(人鬼)数量
    • 左岸(西岸)的乘客数量
    • 右岸(东岸)的乘客数量
    • 可以观察到有一个恒定的值就是乘客的总数不变,东西两岸的乘客与船上的乘客之和不变
    • 两岸人鬼数量的变化是由渡船上的人鬼数量与船的运动方向决定的

在这里插入图片描述

  • 现在思路就清晰了,我们约定人鬼分别用R,G来表示,即:(R,G)。
  • 这里有一个动态的场景
    • 东岸的(R,G)也就是从一开始的(3,3)经过一系列的船来船往变成了(0,0)
    • 我们只要选定一个岸边就行了,因为总和是一样的
    • 每一个渡河中的“东岸场景”都与一个数对(R,G)相对应
    • 东岸所有可能场景(人鬼数),会组成平面上的一个网格,如下图所示

在这里插入图片描述

  • 现在这个数学模型基本确定了,从(3,3)到(0,0)这个过程是加加减减的问题,也就是渡河的方案
  • 拿东岸来说, 如果乘坐2个鬼过去,那么就是从(3,3)到(3,1)的操作,我们可以把(R,G)看作复数或二维向量
  • 现在可以用S表示(R,G),代表一个整体,我们将在一次操作中改变人鬼的数量记为△k\triangle_k△k​, 则有
    • Sk+1=Sk±△kS_{k+1} = S_k \pm \triangle_kSk+1​=Sk​±△k​
    • k表示一次操作(一次渡河方案)
    • 这个式子表示一次渡船操作前和操作后的关系,可见这个△k\triangle_k△k​是船上人鬼的数量

在这里插入图片描述

  • 还有一个需要确定船的方向,船过去船回来加减问题很重要,这个方向如何数字化,而且要求方便计算

  • 设k为摆渡行船的次数(序号,从1开始计数),用奇偶性来表示渡船的方向,从东岸到西岸或从西岸到东岸记1次。显然

    • 船从东到西,k为奇数, 此处东岸乘客数量减少
    • 船从西到东,k为偶数, 此处东岸乘客数量增加
  • 定义一个2维向量dkd_kdk​为第K次渡河的摆渡策略: dk=(rk,gk)d_k = (r_k, g_k)dk​=(rk​,gk​)

    • 其中,rkr_krk​为上船的人数,gkg_kgk​为上船的鬼数,则所有合法(规则:船上最多只能坐2人)的渡河摆渡决策集合D定义如下:
    • D={(r,g)}D = \{(r,g)\}D={(r,g)}
      • r = 2, g = 0;
      • r = 1, g = 0;
      • r = 1, g = 1;
      • r = 0, g = 1;
      • r = 0, g = 2;
  • 还有就是渡河前东岸的安全状态问题,用2维向量Sk=(Rk,Gk)S_k = (R_k, G_k)Sk​=(Rk​,Gk​)定义为第k次渡河前东岸的渡河状态,则安全渡河东岸状态集合S有:

    • S={(R,G)}S = \{(R,G)\}S={(R,G)}
      • R=0,G=0,1,2,3R=0, G=0,1,2,3R=0,G=0,1,2,3
      • R=3,G=0,1,2,3R=3, G=0,1,2,3R=3,G=0,1,2,3
      • R=1,G=1R=1, G=1R=1,G=1
      • R=2,G=2R=2, G=2R=2,G=2
    • 根据规则,推导出安全性检测标准: 在东岸,人数等于3或人数等于0,或人数鬼数相等, 用代码表示相关逻辑为:
      // r表示东岸人数,g表示东岸鬼数
      bool AQ = (r == 3) || (r == 0) || (r == g) // 是否安全
      if(!AQ) continue; // 如果不安全,则舍弃当前决策
      

在这里插入图片描述

  • 可以看到上图中红色的点表示不安全
  • 由之前的 Sk+1=Sk±△k⇔Sk+1=Sk±dk⇔Sk+1=Sk+(−1)kdkS_{k+1} = S_k \pm \triangle_k \Leftrightarrow S_{k+1} = S_k \pm d_k \Leftrightarrow S_{k+1} = S_k + (-1)^k d_kSk+1​=Sk​±△k​⇔Sk+1​=Sk​±dk​⇔Sk+1​=Sk​+(−1)kdk​
    • 注意:K的范围是[1…n],从1开始,到未知待求的n结束
  • 整个模拟过程如下:

在这里插入图片描述

  • 这里算法实现的思想是:迭代 + 枚举 + 递推

    • 迭代:从起始到结束
    • 枚举:所有可能决策
    • 递推:状态转移方程
  • 算法实现:

    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    // 定义描述渡河状态东岸人数与鬼数的结构变量。R: 状态中的人数, G: 状态中的鬼数 
    struct state { int R, G; };
    //结构数组记录渡河时的状态转移过程
    state s[20];
    //记录状态转移过程的决策号,初始化都为0
    int choice[20] = {0};
    //状态号
    int k;
    
    // 摆渡策略(数组) 0号策略不用, 有用的只有5个, 其中从{2,0}到{0,2} 这有用的5个, 决策编号依次为:1,2,3,4,5
    state d[6] = {{0, 0}, {2, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}};
    void display(); // 输出渡河状态
    void transfer_state(); // 渡河状态转移函数
    
    int main() {
        transfer_state();
        display();
        return 0;
    }
    
    void transfer_state() {
        k = 1; //初始状态设为1, 也就是第一次从东岸走,是奇数,减法操作
        s[1].R = 3; //初始状态东岸有3人 
        s[1].G = 3; //初始状态东岸有3鬼
    
        do {
            int fx = 1; //摆渡方向,东向西或西向东
            if (k % 2 == 1) {
                fx = -1; //奇数表明摆渡要从东岸到西岸
            }
            int i; //决策号
    
            // 针对下一状态(次序为k+1,choice数组元素初值为0),依次尝试所有决策(决策号从1到5)
            for (i = choice[k + 1] + 1; i <= 5; i++) {
                //试探采用哪个决策能安全走1步
                int r = s[k].R + fx * d[i].R; //按第i号策略走1步后,东岸的人数 
                int g = s[k].G + fx * d[i].G; //按第i号策略走1步后,东岸的鬼数
                // 判断是否越界
                bool cross = r > 3 || g > 3 || r < 0 || g < 0;
                // (1) 越界,舍弃当前决策
                if (cross) continue;
                bool AQ = (r == 3) || (r == 0) || (r == g); //是否安全
                //(2) 不安全,舍弃当前决策
                if (!AQ) continue;
                bool CHF = false; //是否重复 
                //查历史信息(倒序),仅考虑摆渡方向一致的状态(增量为-2) 
                for (int j = k - 1; j >= 1; j -= 2) {
                    if (s[j].R == r && s[j].G == g) {
                        CHF = true; //若人鬼数一致,则是重复状态 
                    }
                }
                //(3) 重复,则舍弃当前决策,继续(continue)尝试下一决策
                if (CHF) {
                    continue;
                }
                // 按策略渡河,状态号加1
                k++;
                s[k].R = r; 
                s[k].G = g;
                //记录决策号
                choice[k] = i;
                //已找到一个决策,跳出(break)循环,**暂停** 尝试其他策略
                break;
            }
            // 所有摆渡决策都没成功,则需要回退
            if (i > 5) {
                choice[k+1]=0; 
                k--;
            }
        } while (!(s[k].R == 0 && s[k].G == 0)); // 目标是东岸既无人又无鬼
    }
    
    void display() {
        for (int i = 1; i <= k; i++) {
            cout << setw(2) << i << ": choice = " << choice[i] // 决策号
            << " {" << d[choice[i]].R << "," << d[choice[i]].G << "}" // 决策内容
            << " (" << s[i].R << "," << s[i].G << ") "// 状态内容
            << endl;
        }
    }
    

人鬼渡河问题升级

1 ) 问题升级

  • 目标: 将东岸的3人3鬼通过一只小船安全转移到西岸,希望摆渡次数尽可能少
  • 条件:
    • 船的容量有限,一次最多只能坐2人(或2鬼或1人1鬼)
    • 无论是在河的东岸还是在河的西岸,一旦鬼数多于人数,则人被鬼扔到河中
    • 怎样渡河的大权掌握在人的手中
  • 任务: 编写程序,求出所有的渡河方案,要求没有多余的重复步骤

2 ) 分析

  • 视某一时刻东岸的(人,鬼)数对,是状态空间中的坐标点!
  • 于是:
    • 任务转换为从起点状态(3,3)“跳”到终点状态(0,0)
    • 坐标变化操作规则按照题目关于安全性的要求,可得
      • dxy[] = {{1,0}, {0,1}, {1,1}, {2,0}, {0,2}};
    • 对每一个状态,枚举尝试所有可能的决策
    • 若当前状态与终点状态一致,则输出此方案
  • 按照这个思路,这一问题就转换成了跳马问题,使用枚举,递归的方式来解决

在这里插入图片描述

  • 代码实现
    #include <iostream>
    using namespace std;
    struct position { int x, y; }; // 不同决策对应的状态坐标变化
    position dxy[] = {{1,0}, {0,1}, {1,1}, {2,0}, {0,2}};
    // 起始状态,结束状态 
    position start_pos = {3, 3},
            goal_pos  = {0, 0};
    
    // 决策序列的记录
    position path[100]; 
    int num; // 总的方案数
    /// 记录出现次数,防止重复!!!
    int pos_cnt[2][4][4] = {{{0}}};
    
    // 坐标是否相等
    bool IsEq(position pos1, position pos2) {
        return (pos1.x == pos2.x) && (pos1.y == pos2.y);
    }
    
    // 是否完成
    bool IsDone(position pos) { 
        return IsEq(pos, goal_pos);
    }
    
    // 是否有效
    bool IsValid(position pos, int step) {
        // 声明合法性,安全性,重复性
        bool v, s, r;
        // 方向:0表示从左(西)到右(东), 1表示从右到左
        int dir = step % 2; 
        // 合法性检查
        v = (pos.x >= 0) && (pos.x <= 3) && (pos.y >= 0) && (pos.y <= 3); 
        // 安全性检查,根据游戏规则推导出来 
        s = (pos.x == pos.y || pos.x == 0 || pos.x == 3);
        // 重复性检查,根据算法特点推导出来的
        r = pos_cnt[dir][pos.x][pos.y] == 0;
        return v && s && r;
    }
    
    // 计数
    void SetCount(position pos, int step, int cnt) {
        // 获取方向:0表示从左(西)到右(东), 1表示从右到左
        int dir = step % 2;
        pos_cnt[dir][pos.x][pos.y] = cnt;
    }
    
    // 获取新的位置
    position GetNewPos(position pos, int k, int step) {
        // 次序决定方向,方向决定加减
        int dir = (step % 2 == 0) ? -1 : 1;  
        //通过引入方向变量,使下面的新坐标计算公式成为通用的,对两个方向均适用 
        position next_pos = {pos.x + dir * dxy[k].x, pos.y + dir * dxy[k].y}; 
        return next_pos;
    }
    
    void LogStep(position pos, int step) {
        path[step] = pos;
    }
    
    void OutStep(position pos) {
        cout << "(" << pos.x << ", "<< pos.y << ") ";
    }
    
    void OutAll(int step) {
        for (int i=0; i<=step; i++) {
            OutStep(path[i]); 
        }
        cout << endl;
    }
    
    void Jump(position pos, int step) {
        if (IsDone(pos)) { // 是否到达目标?
            num++; // 方案数加1 
            cout << num << ": "; OutAll(step); // 输出方案 
            return;
        }
    
        // 遍历N种方案
        for (int k=0; k<sizeof(dxy)/sizeof(dxy[0]); k++) {
            position next_pos = GetNewPos(pos, k, step);
            if (!IsValid(next_pos, step+1)) continue; // next_pos是否可行?
            SetCount(next_pos, step+1, 1); // 设置次数!!! 
            LogStep(next_pos, step+1); // 记录方案 
            Jump(next_pos, step+1); // 走下一步 
            SetCount(next_pos, step+1, 0); // 清除次数!!!(回溯)
        }
    }
    
    int main() {
        num = 0; // 初始方案数置0 
        SetCount(start_pos, 0, 1); // 第0步在起点(第一次)!!! 
        LogStep(start_pos, 0); // 记录起点 
        Jump(start_pos, 0); // 走第一步
        return 0;
    }
    

代码优化,不要回溯

  • 代码实现:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    struct position { int x, y; };
    position dxy[] = {{1,0}, {0,1}, {1,1}, {2,0}, {0,2}};
    
    struct state {
        int dir;
        position pos; 
    };
    
    state start = {-1, {3, 3}}, goal = {1, {0, 0}};
    state path[100];
    int num;
    
    bool IsEq(state st1, state st2) {
        return (st1.dir == st2.dir) && (st1.pos.x == st2.pos.x) && (st1.pos.y == st2.pos.y);
    }
    
    bool IsDone(state st) { 
        return IsEq(st, goal); 
    }
    
    bool IsValid(state st, int step) {
        /// 1. 合法性检查
        if (st.pos.x < 0 || st.pos.x > 3 || st.pos.y < 0 || st.pos.y > 3) {
            return false;
        }
        /// 2. 安全性检查【根据游戏规则推导出来】
        if (st.pos.x != 0 && st.pos.x != 3 && st.pos.x != st.pos.y) {
            return false;
        }
        /// 3. 重复性检查
        for (int i=step-2; i>=0; i-=2) {
            if (IsEq(st, path[i])) {
                return false;
            }
        }
        return true;
    }
    
    state GetNewState(state st, int k, int step) {
        state next_st = {-st.dir, {st.pos.x + st.dir * dxy[k].x, st.pos.y + st.dir * dxy[k].y}};
        return next_st;
    }
    
    void LogStep(state st, int step) { 
        path[step] = st; 
    }
    
    void OutStep(state st) {
        cout << setw(2) << st.dir << " (" << st.pos.x << ", "<< st.pos.y << ") ";
    }
    
    void OutAll(int step) {
        for (int i=0; i<=step; i++) {
            OutStep(path[i]);
        }
        cout << endl;
    }
    
    void Jump(state st, int step) { 
        // 是否到达目标?
        if (IsDone(st)) {
            num++;
            cout << num << ": "; 
            OutAll(step); 
            return;
        }
        // 遍历N种决策
        for (int k=0; k<sizeof(dxy)/sizeof(dxy[0]); k++) {
            state next_st = GetNewState(st, k, step);
            if (!IsValid(next_st, step+1)) continue;
            LogStep(next_st, step+1); // 记录该决策
            Jump(next_st, step+1); // 转到下一状态
        }
    }
    
    int main() {
        num = 0; // 初始方案数置0 
        LogStep(start, 0); // 记录起点 
        Jump(start, 0); // 从起点出发 
        return 0;
    }
    

相关问题扩展

  • 青蛙换位问题
  • 华容道问题
  • 分水问题
农夫过河逻辑问题与队列应用编程实战 本文还有配套的精品资源,点击获取 简介:农夫过河问题是一个经典的逻辑问题,要求在特定条件下将农夫、狼、羊和菜安全过河。该问题利用队列数据结构进行状态管理和解题,通过队列的建队列、入队列和出队列操作实现对农夫与物品状态的有序规划和执行。本问题的解决方案通常涉及初始化队列、状态循环检查、新状态生成和重复搜索直到找到解决方案或确认无解的步骤。该编程案例可帮助学习者理解如何将逻辑问... 阅读详情

相关推荐

RK3588开发板实战:从零开始移植Ubuntu 24.04(讯为SDK版)

本文详细介绍了如何在RK3588开发板上从零开始移植Ubuntu 24.04系统(讯为SDK版),涵盖开发环境准备、SDK解析、根文件系统定制、驱动适配、系统集成与烧录等全流程。通过实战案例,帮助开发者快速掌握RK3588开发板的系统移植技巧,适用于嵌入式开发与定制化Linux系统构建。

sand8的博客 436

三人三鬼过河问题

三人三鬼过河问题: 三个人和三个鬼在河边,都想要到河的对岸去;河边有一只船,只能搭载两个人、或者两个鬼、或者一人一鬼;如果在岸上或者在船上,鬼的数目多于人的数目,鬼就会把人吃掉。 怎样安排人和鬼的组合上船过河,才能使三个人和三个鬼都安全到河的对岸去呢? 程序思路: 人鬼过河问题实际上可以考虑为状态之间的迁移,或者是构建一个有向图,然后在图中寻找可行的路径。 我们把当前岸边作为左岸,河的对

选择的专栏 1万+

智能体在车联网中的应用:一份详尽到每日的100天学习路线图

这100天的旅程,是一次对毅力、学习方法和工程实践能力的综合考验。它不仅关乎掌握一系列技术点,更关乎培养解决复杂系统性问题的思维模式——将宏观的交通需求分解为微观的智能体决策,再通过多智能体协同涌现出宏观的智能行为。当你完成这份大纲时,你将拥有的不仅是一个项目作品集,更是一套应对“智能体+车联网”乃至更广泛AI+垂直领域挑战的方法论。未来已来,期待你成为构建智能交通新生态的关键贡献者。

IT深耕十余载,大道之简 1332

计算思维_第一周_人鬼渡河

一.题目描述 1.一次最多两人(2人/2归/1人+1鬼) 2.无论在河哪边,鬼比人多就会把人吃掉(船靠岸时人数船和岸一起算) 求一个解决方案 二.解决方案 要找到渡河方案,即一系列“指令” 对于计算机而言,“指令”就是对“数”的运算,因此要确定哪些“数”需要被算 考察本题,可算的量为西岸,船上,东岸的人鬼数量的变化 、那么,设东岸人数R,鬼数G,用(R,G)表示,可以构成如下的4x4网络 要从(...

weixin_42577672的博客 489

第18届全国大学生智能汽车竞赛四轮车控制策略深度解析:从舵机PID到速度闭环

本文深度解析了第18届全国大学生智能汽车竞赛中四轮车的核心控制策略。从舵机PID方向控制的基础原理与机械校准入手,详细阐述了误差计算、PD控制等关键环节;进而深入探讨了基于编码器的速度闭环控制,包括增量式PI算法与速度决策逻辑。文章结合实战经验,提供了方向环与速度环的协同调参思路与避坑指南,旨在帮助参赛者构建稳定、高效的智能车控制系统。

potato的博客 462

3D Slicer肺部CT病灶体积测量:阈值法实操全流程

在医学影像分析中,病灶体积的精准测量是肿瘤评估、疗效随访和科研统计的重要基础。传统逐层手动勾画不仅耗时,且主观差异大,而基于CT值的阈值分割技术,通过设定灰度区间自动提取目标体素,能够快速生成三维分割结果,具有高效、可重复、边界标准统一的优势,尤其适用于肺部实性结节这类与周围肺实质对比度高的病灶。理解体素与CT值的关系,掌握阈值范围的设定逻辑,并配合连通域分析、边缘修正等工程化操作,即可在3D Slicer中稳定获得可靠的体积数据。本文从技术原理出发,系统梳理了DICOM导入、窗宽窗位调节、阈值选择、三维重

weixin_29050271的博客 251

c/c++语言编程实现人狗鸡和白菜过河问题的求解过程.,人鸡狗过河问题 c++编程.doc...

人鸡狗过河问题c编程#include #include typedef struct{int a, b, c, d;} Vector;void Add(Vector *vector1, Vector vector2,Vector* resultVector){resultVector->a = (vector1->a + vector2.a) % 2;resultVector->...

weixin_29819789的博客 323

给排水工程师的SWMM初体验:从软件界面到第一个简单模型的保姆级上手教程

本文为给排水工程师提供SWMM软件的保姆级上手教程,从界面解析到创建第一个简单模型,详细介绍了SWMM的核心功能和操作步骤。通过30分钟的实践指导,帮助新手快速掌握雨水管网建模的基本技能,提升工作效率。

weixin_28736355的博客 323

智力逻辑场景题

同样,2号的方案也会被1号所洞悉,1号并将提出(97,0,1,2,0)或(97,0,1,0,2)的方案,即放弃2号,而给3号一枚金币,同时给4号(或5号)2枚金币。由于1号的这一方案对于3号和4号(或5号)来说,相比2号分配时更优,他们将投1号的赞成票,再加上1号自己的票,1号的方案可获通过,97枚金币可轻松落入囊中。分配方案可写成(97,0,1,2,0)或(97,0,1,0,2)。dp[1] = 1;不过,2号推知3号的方案,就会提出“98,0,1,1”的方案,即放弃3号,而给予4号和5号各一枚金币。

weixin_49631705的博客 1174

用YOLO11-seg玩转裂缝分割:CBAM注意力魔改+轻量化GhostConv实战

本文详细解析了如何利用YOLO11-seg进行裂缝分割任务,结合CBAM注意力机制和GhostConv轻量化改造,显著提升模型性能。通过实战案例展示从数据准备、模型训练到部署优化的全流程,特别针对小目标检测和复杂背景干扰等挑战提供解决方案,最终实现高效准确的裂缝检测系统。

j0k1l2m3n的博客 287

基于方差分解分析气象/水文干旱驱动因素(含MATLAB全代码)

简介基于方差分解方法分析气象/水文干旱驱动因素

WW、forever的博客 801

数据结构与算法笔记:计算思维之经典农夫过河问题C++实现

农夫、羊、狼、菜的过河问题 问题描述 角色:农夫,羊,狼,菜 条件1:船很小,只能装下农夫和其他一个角色 条件2:无人看管,羊吃菜,狼吃羊 问:如何让其他三种角色被农夫平安带着过河? 相关分析 我们可以先用人脑尝试一下相关渡河策略 1 ) 先渡狼,人回来再渡菜,人回来再渡羊 2 ) 先渡菜,人回来再渡狼,人回来再渡羊 以上两种很好想到,而且我们可以知道羊这种角色是不能先渡河过去的,羊需要最后再渡 如果先渡了羊了,之后再渡任何其他角色,都要将羊带回来 可以参考小游戏:http://gameschool

Wang的专栏 3311

YOLOv11 改进入门篇 | 从原理到代码:CBAM 注意力模块的插入与涨点验证

本文介绍了如何在YOLOv11模型中插入CBAM注意力模块以提升检测性能。CBAM包含通道和空间注意力两个子模块,通过双池化操作和MLP学习特征权重。文章详细解析了CBAM原理,提供了PyTorch实现代码,并建议在YOLOv11的Stage-3和Stage-4之间插入CBAM。实验表明,该方法在COCO数据集上使nano和small模型的mAP提升1.7-2.3个百分点,参数量仅增加0.27%,推理延迟增加0.1ms。最后给出了插入位置选择、通道缩减比等调优建议,验证了CBAM作为轻量级注意力模块的有效性

shrgegrb的博客 1301

三人三鬼过河(野人与传教士过河)问题c/c++代码

#include<bits/stdc++.h> using namespace std; vector< pair<int,int> > path; map< vector<int> ,int > vis; void dfs(int La,int Lb,int Ra,int Rb,int flag)// La 左边的好人数 Lb左边的坏人数 flag是左边操作还是右边 { if( (Lb>La&&La) || (Rb&g

辉小歌的博客 1690

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

3人3鬼过河问题

(1)人人人鬼鬼鬼、 鬼鬼 过去 (2)人人人鬼、鬼鬼 鬼回来 (3)人人人鬼鬼、鬼 鬼鬼 过去 (4)人人人、鬼鬼鬼 鬼 回来 (5)人人人鬼、鬼鬼 人人 过去 (6)人鬼、人人鬼鬼 人鬼 回来 (7)人人鬼鬼、人鬼 人人 过去 (8)鬼鬼、人人人鬼 鬼

若星璨,恨逐波 3218

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

野人传教士过河问题

状态空间:一个问题的全部状态及一切可用算符构成的集合。常用一个三元组表示为:(S, F, G),其中,S为问题的所有初始状态集合;F为算符的集合;G为目标状态的集合。状态空间也可用一个有向图来表示,该有向图称为状态空间图。在状态空间图中,节点表示问题的状态,有向边表示算符。请画出本实验的程序流程图。//传教士和野人数量都为三,船每次最多运送2人情况下,算法流程图。

m0_74370400的博客 1413

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

三人三鬼问题解决思路

题目:    3人3鬼过河,船只能坐2个家伙,且那边的鬼都不能比人多,问该如何过河? 问题补充:鬼只要发现他们的数量比人多时就会攻击人,所以不仅是岸上鬼不能比人多,也不能出现 这张图的思想是:首先确定鬼和人的实际状态范围,直接在初期阶段就排除那些干扰项,具体的状态可能是: 1. 人为0,鬼可以是0,1,2,3; 2. 人为3,鬼可以是0,1,2,3; 3. 人数等于鬼数=0,1,2

byteway的专栏 3469

渡河问题(贪心)

现在有一群人,到了一条河旁边,想要过河,但船只有一条,一次最多能载两个人,开到了对面还需要一个人负责把船开回来,而且若多人坐船,速度还是由慢的一个决定,现在求如何分配坐船,使总时间最短。输入t组数据,每组数据第1行输入n,第2行输入n个数,表示每个人过河的时间。输出t行数据,每行1个数,表示每组过河最少时间。

m0_73801775的博客 428

利用动态规划解决袋鼠过河问题

最近开始刷牛客上的题目,由于本科学的算法基本都忘了,因此写几个帖子记录下自己刷题学到的东西,正好复习一下算法了。 我们都知道,动态规划算法是算法设计中非常重要的一种方法,是一个多阶段决策的过程。在使用动态规划算法之前需要先判断问题是否满足优化原则,如果不满足优化原则是不能使用动态规划算法的。举个最简单的例子,已知S是起点,T是终点,在S和T之间有三个中间节点,每个节点间的路径都有两条,代价为2或者

vanturman的博客 5377

用编程解决过河问题

很久没有做题了,突然很怀念,于是心血来潮,想起了曾经小弟叫我做的这道趣味题,就花了X个小时(此处不好意思打出来,各位脑补吧)的时间,终于解决了它,那种久违的成就感好像又回来了……但是我的方法不是特别好,代码有点长(以我的水平只能这样了)。不过还是打算把它贴出来,纪念一下过去。有一条河,河边有猎人,狼,一个男人带着两个小孩,还有一个女人带着两个 问题补充: 出一道题让大家思考: 有一条河,河边有猎人,.........

零怀念的博客 3590

python解决过河问题

只有一艘船,三个商人三个仆人过河,每一次船仅且能坐1~2个人,而且任何一边河岸上仆人比商人多的时候,仆人会杀人越货。 这是一个很经典的过河问题。题解: #允许状态集合,例num=3 #S={(x,y)|x=0,y=0,1,2,3;x=3,y=0,1,2,3;x=y=1,2} x是此岸的商人数,y是此岸的仆人数 #允许决策集合,例boat_limit=2 #D={(u,v)|1&lt;=u+v...

your_answer的博客 9841

人工智能课程实验·过河问题/实验一 知识表示方法

人工智能课程实验·过河问题/实验一 知识表示方法   状态空间法实验。从前有一条河,河的左岸有m(=3)个传教士、m(=3)个野人和一艘最多可乘n(=2)人的小船。约定左岸,右岸和船上

©TyxMaek 3593

三人三鬼过河问题的解

int h1[10][3]={{0,0,0},{0,1,-1},{0,2,-1},{0,3,-1},{1,1,-1},{2,2,-1},{3,0,-1},{3,1,-1},{3,2,-1},{3,3,-1}};int h2[10][3]={{0,0,0},{0,1,-1},{0,2,-1},{0,3,-1},{1,1,-1},{2,2,-1},{3,0,-1},{3,1,-1},{3,

huahuahua12的专栏 2733

人鬼过河(智力游戏)

<br /><br />《人鬼过河》 游戏介绍: <br />把人和鬼都送到对岸,任何一边鬼都不能比人多,否则鬼吃人,游戏结束,5分钟不能完成者,智商属于底下!^-^    

洪欣的专栏 3452
上一篇: 数据结构与算法笔记:计算思维之分书和八皇后问题
下一篇: 数据结构与算法笔记:抽象思维之对比算法,发现共性(下楼梯台阶和象棋跳马问题算法重构)
Wang's Blog
博客等级 码龄12年 7418粉丝 2402原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值