• 三个桶等分八升水


    三个桶等分八升水

    ​ 有这样一道智力题目:有三个容积分别是3升、5升和8升的水桶,其中容积为8升的水桶中装满了水,容积为3升和容积为5升的水桶是空的。3个水桶都没有体积刻度,现在需要将大水桶中的8升水等分成两份,每份都是4升水,附加条件是只能使用另外两个空水桶,不能借助其他辅助容器。

    ​ 这是一个很经典的问题,但是并不难,大部分人都可以在一分钟内给出答案。不过,很多人可能没有注意到,这个问题的答案不止一个。先来看一个最常见的答案,也是目前已知最快的操作步骤,一共倒水7次。

    1)从8升水桶中倒5升水到5升水桶中
    2)从5升水桶中倒3升水到3升水桶中
    3)从3升水桶中倒3升水到8升水桶中
    4)从5升水桶中倒2升水到3升水桶中
    5)从8升水桶中倒5升水到5升水桶中
    6)从5升水桶中倒1升水到3升水桶中
    7)从3升水桶中倒3升水到8升水桶中

    ​ 最后的结果是5升水桶和8升水桶中各有升水,其实还有很多种答案,我们就不一一列举了,到底有多少种答案?水从水桶间倒来倒去,情况太多了,我们算不出来,但是计算机可以。设计一个算法,让计算机帮助我们把所有的答案都找出来,这就是本章的内容。

    问题与求解思路

    ​ 如果用人的思维方式,那么解决这个问题的关键是怎么通过倒水凑出确定的1升水或能容纳1升水的空间,三只水桶的容积分别是3、5和8,用这三个数做加减运算,可以得到很多组答案,例如:

    3 - (5 - 3) = 1

    ​ 但是计算机并不能理解这个“1”的重要性,很难按照人类的思维方式按部就班地推导答案,因此计算机解决这个问题,通常会用“穷举法”。为什么用“穷举法”呢?因为这不是一个典型意义上的求解最优解的问题,虽然可能暗含了求解倒水次数最少的方法的要求,但就本质而言,常用的求解最优解问题的高效方法都不适用于此问题。如果能够穷举解空间的全部合法解,然后通过比较找到最优解也是一种求解最优解的方法。

    倒水动作的数学模型

    ​ 一个合法的倒水动作包含三个要素:倒出水的桶、倒入水的桶和倒水体积。我们用一个三元组来描述倒水动作:<font face =“consolas">{from, to, water}from是指从哪个桶中倒水,to是指将水导向哪个桶,water是此次倒水动作所倒的水量。倒水动作的数据结构定义如下。

    typedef struct tagACTION{
        int from;
        int to;
        int water;
    }ACTION;
    

    ​ 包含动作的倒水状态定义如下:

    struct BucketState
    {
        ···
        int bucket_s[BUCKET_COUNT];
        ACTION cuiAction;
    };
    

    状态树的遍历

    bool BucketState::CanTakeDumpAction(int from, int to)
    {
        assert((from >= 0) && (from < BUCKETS_COUNT));
        assett((to >= 0) && (to < BUCKETS_COUNT));
        
        if( (from != 0)
           && !IsBucketEmpty(from)
           && !IsBucketEmpty(to) )
        {
            return true;
        }
            
        return false;
    }
    
  • 相关阅读:
    Python教程(2.2)——数据类型与变量
    Python教程(2.1)——控制台输入
    Python教程(1.2)——Python交互模式
    (译)割点
    Python教程(1.1)——配置Python环境
    Python教程(0)——介绍
    [HDU1020] Encoding
    [HDU1004] Let the balloon rise
    扩展中国剩余定理 exCRT 学习笔记
    51nod 1943 联通期望 题解【枚举】【二进制】【概率期望】【DP】
  • 原文地址:https://www.cnblogs.com/coding365/p/12592982.html
Copyright © 2020-2023  润新知