一个简单算法题是 10个苹果有多少种分法(整个),比如 1 1 8和 1 8 1、8 1 1是一样的。
它的本质还是M个苹果和N个盘子的问题,这里有个特殊的条件是M<=N。
简单分析下:
M个苹果 分成N份
第一份是X1个,剩下的M-X1个苹果和N-1份;
第二份是X2个,剩下的M-X1-X2个苹果和N-2份;
······ ······ ······
第n份是Xn个,剩下的M-X1-X2···-Xn个苹果和1份;
最终出口还是剩下的份数为1,不能再分了。
/**
* 递归
*
* @param remain 剩余个数
* @param num 分几次
* @param print 打印前缀
* @param start 开始值
*/
public static void deep(int remain, int num, String print, int start) {
/**
* remain个苹果有num种分法,边界条件是num=1,结束当前分法,加上remain>=start是为了去重(前面的分法已经覆盖)
* 主要思想:M个苹果有num种分法,确定第一个个数X1,剩下M-X1个和num-1种分法依然符合上述的思想,可以继续递归至
* 次数为1,当前这个分法结束。
*/
if (num == 1 && remain >= start) {
System.out.print(print + remain);
System.out.print(" & ");
return;
}
/**
* j为什么要从start开始?
* 因为 2_1_7 和 1_2_7是等效的,后者在操作的时候已经涵盖了前者的情况
*/
for (int j = start; j <= remain - start; j++) {
int num1 = num - 1;
String print1 = print + j + "_";
deep(remain - j, num1, print1, j);
}
}
调用处按具体逻辑处理
public static void main(String[] args) {
System.out.print("输入M个苹果:");
Scanner scanner = new Scanner(System.in);
int M = scanner.nextInt();
System.out.print("输入N个盘子:");
int N = scanner.nextInt();
for (int i = 1; i <= Math.min(M, N); i++) {
deep(M, i, "", 1);
System.out.println();
}
}
总共有多少种不同的分法,打印的地方累加即可。