有 n(1\leq n < 10)n(1≤n<10) 个升序排序的互不相同的数 a_ia i ,求出:从中任取 r(0<r \le n)r(0<r≤n) 个数的所有组合情况。 输入格式 第一行输入 nn、rr。 第二行 nn 个正整数 a_i(1\leq a_i \leq 100)a i (1≤a i ≤100)。 输出格式 按特定顺序输出所有组合。 特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。 格式说明 输出时每行末尾的多余空格,不影响答案正确性 输入、输出要求 要求使用「文件输入、输出」的方式解题,输入文件为 combine.in,输出文件为 combine.out C++代码 C++ C++
时间: 2023-02-05 07:12:13 浏览: 175
这题可以使用组合数学中的组合生成函数来做。
假设给定的升序数列为 [a_1, a_2, …, a_n],组合生成函数为:
C(x) = a_1x^0 + a_2x^1 + a_3x^2 + … + a_nx^(n-1)
在 C(x) 中,任意项的系数即为组合的一种情况,例如 C(x) = x^3 + 2x^2 + 3x^1 + 4x^0 表示有四种组合情况: (a_4, a_3, a_2), (a_4, a_3, a_1), (a_4, a_2, a_1), (a_3, a_2, a_1)。
如果需要从数列中取出 r 个数的所有组合,可以使用如下方法:
1. 先计算出 C(x) 的第 r+1 项到最后一项的和。
2. 对计算出的和进行逆运算,即对其求导数,得到 C'(x)。
3. 求出 C'(x) 的第 0 项到第 r-1 项的系数。
注意,组合生成函数的求和和求导数是多项式的基本运算,因此可以使用多项式的快速幂算法进行。
下面是代码实现:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define not !
#define and &&
#define or ||
#define ri register int
#define rep(inc, frm, to) for (ri inc = frm; inc < (to); ++inc)
#define rep2(inc, frm, to) for (ri inc = frm; inc > (to); --inc)
#define setbit(x, y) x |= 1 << y
#define clrbit(x, y) x &= ~(1 << y)
#define getbit(x, y) x >> y & 1
#
阅读全文