题目描述
小蓝有黄绿蓝三种颜色的小球,分别为R,G,B 个。同样颜色的小球没有区别。
小蓝将这些小球从左到右排成一排,排完后,将最左边的连续同色小球个数记为 t1,将接下来的连续小球个数记为t2,以此类推直到最右边的小球。
请问,总共有多少总摆放小球的方案,使得 t1,t2,⋯ 为严格单调递增序列,即 t1≤t2≤t3≤⋯。
输入描述
输入一行包含三个整数 R,G,B。
其中,0≤R,G,B≤50。。
输出描述
输出一个整数,表示答案。
输入输出样例
示例 1
输入
3 6 0
输出
3
样例说明
用 r 表示红球,g 表示绿球,可能的方案包括:
rrrgggggg
grrrggggg
ggrrrgggg
运行限制
最大运行时间:1s
最大运行内存: 128M
思路
因为全排列时间复杂度巨大,所以用深搜选择性的查找符合条件的序列
本题可以想象成: 手上拿着这些球,然后往地上放,每次拿与上次不同颜色的小球放,且放的数量必须比上次多,如果最后手上没球了,就记下这个序列;如果最后手上的球在符合规则的情况下放不进去了,就不继续进行了,并且把刚刚放的再拿回来,重新放,如果还不行,就一直往回拿直到可以放另一种情况为止。直到所有情况全部模拟完。
JAVA代码
import java.util.Scanner;
public class 排列小球 {
static int[] a = new int[3];
static int count = 0;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int sum = 0;
for (int i = 0; i < 3; i++) {
a[i] = scanner.nextInt();
sum += a[i];
}
dfs(sum, 0, -1); // 没放入序列的小球,上一次放的球数,上一次放的球的颜色
System.out.println(count);
}
private static void dfs(int sum, int num, int lastColor) {
//球全部放完,这是一种情况
if (sum == 0) {
count++;
return;
}
for (int i = 0; i < 3; i++) {
if (i == lastColor) {//不能挨着放同种颜色
continue;
}
for (int j = num + 1; j <= a[i]; j++) {
a[i] -= j;//减少手上该种颜色的球的数量
dfs(sum - j, j, i);//j为放入序列的球数 i为这次放的球的颜色
a[i] += j;//深搜完一种情况后,恢复手上该颜色球的数量 (回溯)
}
}
}
}