给定m个长度为n的数组,要求从每一个数组中取出一个数字然后相加,这样的取法总共有n^mnm种。
问相加之后和最小的n种是多少。
输入
第一行输入两个整数m, n (1 \le m \le 100, 1 \le n \le 2000)m,n(1≤m≤100,1≤n≤2000)。
接下来m行,每行n个整数,描述每一个数组。数组中的元素非负,且不超过1万。
输出
按从小到大输出前n小的和。
样例
输入
复制
2 3 1 2 3 2 2 3
输出
复制
3 3 4
从最小和到次小和依次枚举,然后dfs找出每个和的情况。
#pragma warning(disable:4996) #include <iostream> #include <cstdio> #include <numeric> #include <cstring> #include <vector> #include <algorithm> #include <functional> #define inf 0x3f3f3f3f int main() { int m, n; scanf("%d%d", &m, &n); std::vector<std::vector<int>> array(m, std::vector<int>(n)); int k = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { scanf("%d", &array[i][j]); } sort(array[i].begin(), array[i].begin() + n); } std::function<void(int, int, int)> dfs = [&](int arNum, int cur, int sum)->void { if (arNum >= m) { if (cur) return; if (k) putchar(' '); printf("%d", sum); k++; return; } for (int i = 0; i < n; i++) { if (k >= n || array[arNum][i] - array[arNum][0] > cur) { return; } dfs(arNum + 1, cur - array[arNum][i] + array[arNum][0], sum + array[arNum][i]); } }; for (int i = 0; i <= 10000; i++) { if (k >= n) break; dfs(0, i, 0); } return 0; } /* 5 10 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 */
如果觉得有帮助,点个推荐啦~