回溯所有可能的选择葡萄酒瓶的方法的解决方案

时间:2018-06-03 11:57:24

标签: java dynamic-programming backtracking

我刚开始练习回溯和DP相关的问题。我正在经历这个org.assertj.core.util.BigDecimalComparator。关于酒瓶选择问题。我首先想写一个代码来打印所有可能的选择葡萄酒瓶的方法。

问题陈述:
   想象一下,你有一系列N种葡萄酒在一个架子上彼此相邻。为简单起见,让我们从左到右对葡萄酒进行编号,因为它们分别以1到N的整数站在货架上。而对于销售,您可以选择左侧的那个或右侧的那个。打印所有可能的方式,葡萄酒瓶可以出售?

我的代码如下。

public static void backtrackWineAll(List<Integer> priceList, List<Integer> choosen) {

        if(priceList.isEmpty()) {
            System.out.println(choosen);
        }
        else {

            Integer first = priceList.remove(0);
            choosen.add(first);//choose the first bottle.

            backtrackWineAll(priceList, choosen);

            choosen.remove(choosen.size()-1);
            priceList.add(0, first);


            int lastPos = priceList.size()-1;
            Integer last = priceList.remove(lastPos);
            choosen.add(last); //choose the last bottle.

            backtrackWineAll(priceList, choosen);

            choosen.remove(choosen.size()-1);
            priceList.add(last);

        }                       
    }

它不起作用。它打印结果两次。谁能指出出了什么问题?

关于如何处理DP问题的任何建议?

感谢。

1 个答案:

答案 0 :(得分:0)

如果priceList的大小为1,则选择第一个瓶子与选择最后一个瓶子相同。因此,在这种情况下,您应该只选择第一个或最后一个瓶子。

一种方法是,如果priceList的大小大于1,则只选择最后一瓶:

public static void backtrackWineAll(List<Integer> priceList, List<Integer> choosen) {

    if(priceList.isEmpty()) {
        System.out.println(choosen);
    } else {
        Integer first = priceList.remove(0);
        choosen.add(first);//choose the first bottle.

        backtrackWineAll(priceList, choosen);

        choosen.remove(choosen.size()-1);
        priceList.add(0, first);

        if (priceList.size () > 1) { // the added condition
            int lastPos = priceList.size()-1;
            Integer last = priceList.remove(lastPos);
            choosen.add(last); //choose the last bottle.

            backtrackWineAll(priceList, choosen);

            choosen.remove(choosen.size()-1);
            priceList.add(last);
        }
    }
}

换句话说,一旦你选择了n-1瓶,只有一种方法可以选择下一个(最后剩下的)瓶子。

对于[10,20,30,40,50]的输入列表,它打印输出:

[10, 20, 30, 40, 50]
[10, 20, 30, 50, 40]
[10, 20, 50, 30, 40]
[10, 20, 50, 40, 30]
[10, 50, 20, 30, 40]
[10, 50, 20, 40, 30]
[10, 50, 40, 20, 30]
[10, 50, 40, 30, 20]
[50, 10, 20, 30, 40]
[50, 10, 20, 40, 30]
[50, 10, 40, 20, 30]
[50, 10, 40, 30, 20]
[50, 40, 10, 20, 30]
[50, 40, 10, 30, 20]
[50, 40, 30, 10, 20]
[50, 40, 30, 20, 10]