思路:
分为n次掷出,但是为了避免重复,要求下一次掷出结果必须大于等于上一次掷出结果
上一次掷完后必然会对下一次能掷出的结果产生影响
如图:
4个骰子掷出20点
第一个骰子应该是掷出结果最小的骰子
第一个骰子取值的约束是
min:后面的骰子全是6,第一个骰子也能取1,所以不能小于2,
max:如果第一个是6,后面都得是6,显然不满足20
第二个骰子
第一种2情况取值的约束
min:必须大于第一个骰子的点数,必须大于18-(2*6)
max:不能大于6
不再详细解释
代码如下:
public static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) {
List<int[]> result = dicing(new int[5],6, 5, 23);
result.stream().forEach((l) -> System.out.println(Arrays.toString(l)));
System.out.println(count.get());
}
public static List<int[]> dicing(int[] arr,int lastValue,int remainingDice, int remainingPoint) {
List<int[]> result = new ArrayList<>();
if (remainingDice == 1) {
if (lastValue >= remainingPoint) {
int[] temp = Arrays.copyOf(arr, arr.length);
temp[arr.length-remainingDice] = remainingPoint;
result.add(temp);
}
} else {
count.getAndIncrement();
int max = findMin(lastValue, remainingPoint - remainingDice + 1, 6);
int min = findMax(remainingPoint / remainingDice, 1);
for(int i = max;i>=min;i--){
int[] temp = Arrays.copyOf(arr, arr.length);
temp[arr.length-remainingDice] = i;
result.addAll(dicing(temp,i, remainingDice-1, remainingPoint-i));
}
}
return result;
}
public static int findMin(int a, int b, int c) {
int min = a;
if (min > b) {
min = b;
}
if (min > b) {
min = c;
}
return min;
}
public static int findMax(int a, int b) {
int max = a;
if (max < b) {
max = b;
}
return max;
}
4个骰子20点,结果如下:
[6, 6, 6, 2]
[6, 6, 5, 3]
[6, 6, 4, 4]
[6, 5, 5, 4]
[5, 5, 5, 5]
7
5个骰子23点,结果如下:
[6, 6, 6, 4, 1]
[6, 6, 6, 3, 2]
[6, 6, 5, 5, 1]
[6, 6, 5, 4, 2]
[6, 6, 5, 3, 3]
[6, 6, 4, 4, 3]
[6, 5, 5, 5, 2]
[6, 5, 5, 4, 3]
[6, 5, 4, 4, 4]
[5, 5, 5, 5, 3]
[5, 5, 5, 4, 4]
20
转载于:https://blog.51cto.com/syli25/1754917