倒水问题

问题:我们经常会遇见这些问题比如给你一个容量为5升的杯子和一个容量为3升的杯子,水不限使用,要求精确得到4升水并写出算法。

回答:1) 直接以简答的方式给定方案

这个比较简单,即便是不知道什么原理,也可以很快凑出来。假设两个杯子分别为x 5升杯, y  3升杯 :  装满 x  ; x -> y  ;清空Y  ;x -> y  ;装满 x  ;x -> y

解决方案会有多个,写出一个即可。

2) 编程实现

解法也比较多,我首先想到的DFS(深度优先)搜索,每次我们有6种选择,只要不断的尝试下去,总可以搜索完所有的状态,找到一个解。也可以用宽度优先搜索(BFS)。

使用DFS搜索实现的Java代码:

/**
 * @author coder
 * @copyright www.acmerblog.com
 */
public class PourWater {
    //所有的6中操作。
    static String operations[] = {" 装满 x ", " 装满 y "," 清空X ", " 清空Y ", " x -> y ", " y -> x "};
    static Stack<Integer> stack = new Stack<Integer>();
    static int L1,L2 ;//两个杯子的容量
    static int target; //目标容量
    static int len;
    //防止重复搜索
    static boolean dp[][] ;
    public static void dfs(int x,int y){
        if(dp[x][y]) return;
        dp[x][y] = true;
        //找到解决方案
        if(x == target || y == target){
            System.out.println("dfs方法 一个倒水方案:");
            for(int oper:stack)
                System.out.println(operations[oper]);
            return;
        }
        stack.push(0);
        dfs(L1,y);
        stack.pop();

        stack.push(1);
        dfs(x,L2);
        stack.pop();

        stack.push(2);
        dfs(0,y);
        stack.pop();

        stack.push(3);
        dfs(x,0);
        stack.pop();

        //x向y倒水
        stack.push(4);
        if(x >= (L2-y) )  //x倒不完,还有剩余
            dfs(x - (L2-y),L2);
        else
            dfs(0 ,y + x); //x没有剩余
        stack.pop();

        //y向x倒水,需要判断能否倒完
        stack.push(5);
        if(y >= (L1-x))
            dfs(L1,y - (L1-x));
        else
            dfs(0,y + x);
        stack.pop();
    }

    public static void main(String[] args) {
         L1 = 5;
         L2 = 3;
        target = 4;
         len = Math.max(L1, L2) + 1;
         dp = new boolean[len][len];
        dfs(0,0);
    }
}

原文地址:https://www.cnblogs.com/benchao/p/4516231.html