You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

给定正整数S与n,输出和为S的n元降序不同子集

解决生成固定长度、和为指定值的降序整数组合问题

看起来你正在尝试实现一个函数,生成所有长度为n且元素和为S的非递增整数组合(也就是你说的不同子集,这里其实是组合,因为不考虑顺序,只保留降序形式避免重复)。先帮你梳理核心逻辑,然后修正你的代码~

问题核心明确

我们需要生成的组合必须满足三个条件:

  • 每个组合的长度恰好是n
  • 所有元素的和等于S
  • 组合是非递增排列(降序),确保不会出现重复组合(比如4+2+1和2+4+1视为同一个,只保留前者)

比如你举的例子:S=7,n=3,输出的四个组合就是符合要求的所有可能。

现有代码问题分析

你当前的函数partitions(int X, int Y)参数命名模糊(推测X是和S,Y是长度n),且终止条件if (X <= 1 && X <= X - Y + 1)逻辑不通,递归部分的min(X - 1, Y)也不对——Y是长度,不是元素的最大值限制,这里应该限制当前元素的最大值,才能保证生成的组合是非递增的。

修正后的完整代码

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

// 辅助递归函数:remaining_sum=剩余需凑的和,remaining_len=剩余需的元素个数,max_num=当前元素允许的最大值(保证非递增)
void helper(int remaining_sum, int remaining_len, int max_num, vector<int>& current, vector<vector<int>>& result) {
    // 终止条件:只剩一个元素,直接加入当前组合
    if (remaining_len == 1) {
        if (remaining_sum >= 1 && remaining_sum <= max_num) {
            current.push_back(remaining_sum);
            result.push_back(current);
            current.pop_back(); // 回溯,清理当前组合
        }
        return;
    }
    // 当前元素的最大值:不能超过max_num,同时不能超过remaining_sum - (remaining_len-1)(剩下的元素至少每个是1)
    int upper = min(max_num, remaining_sum - (remaining_len - 1));
    // 从大到小遍历,保证组合非递增
    for (int y = upper; y >= 1; --y) {
        current.push_back(y);
        // 递归处理剩余的和、长度,下一个元素的最大值不能超过当前元素y
        helper(remaining_sum - y, remaining_len - 1, y, current, result);
        current.pop_back(); // 回溯,尝试下一个可能的元素
    }
}

vector<vector<int>> partitions(int S, int n) {
    vector<vector<int>> result;
    vector<int> current;
    // 只有当S >=n时才有解(n个元素最小和为n,每个元素至少1)
    if (S >= n) {
        // 初始调用:第一个元素的最大值为S - (n-1),保证剩下n-1个元素至少能取1
        helper(S, n, S - (n - 1), current, result);
    }
    return result;
}

// 按要求格式打印结果
void printResult(const vector<vector<int>>& res) {
    for (size_t i = 0; i < res.size(); ++i) {
        const auto& combo = res[i];
        for (size_t j = 0; j < combo.size(); ++j) {
            if (j > 0) cout << " + ";
            cout << combo[j];
        }
        if (i != res.size() - 1) cout << " ";
    }
    cout << endl;
}

// 示例调用
int main() {
    int S = 7, n = 3;
    auto res = partitions(S, n);
    printResult(res); // 输出:5 + 1 + 1 4 + 2 + 1 3 + 3 + 1 3 + 2 + 2
    return 0;
}

代码逻辑解释

  1. 辅助递归函数helper:

    • 用max_num限制当前元素的最大值,确保后续元素不会超过当前元素,从而维持非递增顺序,彻底避免重复组合。
    • 回溯机制:每次加入当前元素后递归,递归完成后移除该元素,尝试下一个可能的取值。
  2. 终止条件处理:当只剩1个元素时,只要该元素在合法范围内(1到max_num),就将其加入当前组合并存入结果。

  3. 主函数partitions:先判断S >=n(如果S小于n,n个元素的最小和都达不到S,直接返回空结果),再启动递归生成组合。

  4. 打印函数printResult:严格按照你要求的格式输出,组合之间用空格分隔,元素之间用+连接。

测试验证

当S=7,n=3时,运行代码会输出你期望的结果:5 + 1 + 1 4 + 2 + 1 3 + 3 + 1 3 + 2 + 2,完全符合要求。

内容的提问来源于stack exchange,提问作者Karl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:53:32