题目来源:https://www.luogu.com.cn/problem/P1025
题目大意:
将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5;
1,5,1;
5,1,1.
问有多少种不同的分法。
输入格式
n,k (6<n≤200,2≤k≤6)
输出格式
1个整数,即不同的分法。
说明/提示
四种分法为:
1,1,5;
1,2,4;
1,3,3;
2,2,3.
==================================================================================================
个人还是对这类问题采用递归的方法(因为并不会动归)。
将一个数拆分为M个数之和,问共有多少种分法。我们很容易可以想到,求所有的可能性,采用DFS可以满足这个条件。这里有个难点就是,不能出现重复的组合,因此我们要对这个DFS稍加处理:我们可以设定这几个数是按从小到大的顺序排列的,那么我们就可 以保证[1,1,5]与[1,5,1]以及[5,1,1]不会同时被算进去。而由于我们的设定,所以在确定前面的一个数X之后,下一位数Y是有一个上下限的,Y的下限无疑就是X,而Y的上限,我们可以通过数学表达式来确定:SUM+(M-K)*Y <= N,其中的SUM代表当前确定的K个数的和。所以,在经过分析之后,我们可以得出以下代码:
import java.util.Scanner; public class Main { public static int ans = 0; public static int N, M; public static void main(String[] args) { Scanner sc = new Scanner(System.in); N = sc.nextInt(); //the num M = sc.nextInt(); //the number of partitions DFS(0, 1, 0); System.out.println(ans); } public static void DFS(int idx, int cur, int sum){ //idx:当前位置 cur:当前的数 sum:当前的和 if (idx == M){ if (sum == N){ ans++; } return; } for (int i = cur; sum + i * (M - idx) <= N ; i++){ DFS(idx + 1, i, sum + i); } } }