BZOJ3260跳题解
题目
题解
看到题, 一眼就觉得没有思路, 所以选择打表找规律:
1 1 1 1 1 1 1 1
1 2 3 4 5 6 7
1 3 6 10 15 21
1 4 10 20 35
1 5 15 35
1 6 21
1 7
1
观察发现最小值好像就是:
\[\dbinom{n + m + 1}{max (n, m) + 1} + max (n, m)
\]
然后, 就做完了
接着的神奇故事
用了上述的神奇式子以后, 我们就可以飞快的打出代码:
//两个凡是:
//凡是将难度反过来的都是毒瘤
//凡是卡常的都是毒瘤
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 1000
#define INF 1000000007
long long Pow (long long a, int b) {
long long ans = 1;
while (b) {
if (b & 1) {
ans *= a;
ans %= INF;
}
a *= a;
a %= INF;
b >>= 1;
}
return ans;
}
long long C(long long n, long long m) {
m = min (n - m, m);
long long ans = 1;
long long sum = 1;
for (long long i = 1; i <= m; i ++) {
ans *= ((n - i + 1) % INF);
ans %= INF;
sum *= i;
sum %= INF;
}
ans *= Pow (sum, INF - 2);
ans %= INF;
return ans;
}
int main () {
long long n, m;
scanf ("%lld %lld", &n, &m);
if (n < m) {
swap (n, m);
}
printf ("%lld", (C(n + m + 1, n + 1) + n % INF) % INF);
}
但事实上, 我开始打的是这个样的:
//两个凡是:
//凡是将难度反过来的都是毒瘤
//凡是卡常的都是毒瘤
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 1000
#define INF 1000000007
long long Pow (long long a, int b) {
long long ans = 1;
while (b) {
if (b & 1) {
ans *= a;
ans %= INF;
}
a *= a;
a %= INF;
b >>= 1;
}
return ans;
}
long long C(long long n, long long m) {
m = min (n - m, m);
long long ans = 1;
for (long long i = 1; i <= m; i ++) {
ans *= (n - i + 1);
ans %= INF;
}
for (long long i = 1, k = Pow (m, INF - 2); i <= m; k = (k * (m - i + 1)) % INF, i ++) {
ans *= k;
ans %= INF;
}
return ans;
}
int main () {
long long n, m;
scanf ("%lld %lld", &n, &m);
if (n < m) {
swap (n, m);
}
printf ("%lld", (C(n + m + 1, n + 1) + n % INF) % INF);
}
???
我就这样打了一个莫名其妙的 \(C\) , 又莫名其妙地过了所有小样例和所有手造的数据。
???