洛谷P4369
题意大意
给你一个数 \(x\) , 要求写成 \(k\) 个组合数的和, 且要求: \(C_n^m\) 中 $ 0 \leqslant m \leqslant n \leqslant x$
即:我们要找到 \(k\) 个组合数,让他们的和等于 \(x\).
分析
我们观察到数据范围,不可能让你写暴力, 所以我们就要考虑有没有规律了
然后我们列出组合数
n = 0 1
n = 1 1 1
n = 2 1 2 1
n = 3 1 3 3 1
n = 4 1 4 6 4 1
n = 5 1 5 10 10 5 1
n = 6 1 6 15 20 15 6 1
我们知道 \(C_n^0 = C_n^n = 1\), \(C_n^1 = C_n^{n - 1} = n\)
然后题目中说任意一组解即可,那我们又可以玩点奇怪的了/xyx
\(x = \sum\limits_{i = 1}^{k - 1}1 + (x - k + 1)\)
$\ \ \ \ \sum\limits_{i = 1}^{k - 1}C_i^0 + C_{x - k + 1}^1 $
题目中说,不可以相同, 但是只要 \(n\) 或者 \(m\) 不相同就行了,我们上面的式子是没有 \(n\) 和 \(m\) 都相同的情况的,所以我们可以大胆使用(幸亏有SPJ)
当然方式有很多种,也可以自己尝试,反正我觉得这种最简单
code:
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#define int long long
#define rr register
#define inf 1e9
#define MAXN 100010
using namespace std;
inline int read() {
int s = 0, f = 0;
char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
}
void print(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) print(x / 10);
putchar(x % 10 + 48);
}
int x, k;
signed main() {
x = read();
k = read();
for (rr int i = 1; i <= k - 1; i++) cout << i << " " << 0 << "\n";
cout << x - k + 1 << " " << 1 << "\n";
}
时间会刺破青春表面的彩饰,会在美人的额上掘深沟浅槽;会吃掉稀世之珍!天生丽质,什么都逃不过他那横扫的镰刀。
博主写的那么好,就不打赏一下么(打赏在右边)