我刚开始练习回溯和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问题的任何建议?
感谢。
答案 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]