月度归档:2026年04月

整数划分问题3

有一个整数 n,请列出把整数 n 划分为若干个正整数的每一种方法,这些正整数必须选自数组 a。数组 a 中可能有重复元素,每个可以选择一次。
例如对 n = 6,a = {1, 1, 2, 2, 3, 4},n = 1 + 1 + 2 + 2 是可以的,数组 a 中有 2 个 1 和 2 个 2 可供选择;n = 2 + 2 + 2 则不正确,因为数组 a 中没有 3 个 2。

【输入格式】

输入共 2 行:
第 1 行,1 个正整数 n,k;
第 2 行,k 个正整数 a0,a1,,ak1为数组 a 中的元素。

【输出格式】

输出共若干行:
每行为用空格隔开的若干个正整数,为一种 n 划分为若干个正整数的方法,每组数按在 a 中的下标从小到大输出。若两种方法中前 k−1 个数在 a 中的下标相同,则第 k 个数的下标更小的在前。如果两种方法选取的数在 a 中的下标不全相同,则视为不同的方法。
例如对 n = 6,a = {1, 1, 2, 2, 3, 4},选取 a 的 0,2,4 或 0,3,4 号元素都会得到 n = 1 + 2 + 3,两者都要在合适的位置分别输出。

【输入输出样例#1】

输入#1

6 6
1 1 2 2 3 4

输出#1

1 1 2 2
1 1 4
1 2 3
1 2 3
1 2 3
1 2 3
2 4
2 4

【数据范围】

1n,a0,a1,,ak1109;1k20

【代码示例】

#include <bits/stdc++.h>
using namespace std;
int n, k, a[25], b[25];

void dfs(int step, int last, int sum) {
	if (step > n || last > n || sum >= k) {
		if (sum == k) {
			for (int i = 1; i < step; i++)
				cout << a[b[i]] << ' ';
			cout << endl;
			return;
		} else {
			return ;
		}

	}
	for (int i = last; i <= n; i++) {
		b[step] = i;
		dfs(step + 1, i + 1, sum + a[i]);
	}
}

int main() {
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	dfs(1, 1, 0);
}