AtCoder Beginning Contest 156

不会组合数学被吊打了……

题目链接:https://atcoder.jp/contests/abc156


A:

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 int n, r;
15 
16 int main() {
17     cin >> n >> r;
18     if (n >= 10) cout << r << endl;
19     else cout << r + 100 * (10 - n) << endl;
20     return 0;
21 }
View Code

B:

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 int n, k;
15 
16 int main() {
17     cin >> n >> k;
18     int ans = 0;
19     while (n) {
20         ans++;
21         n /= k;
22     }
23     cout << ans << endl;
24     return 0;
25 }
View Code

C:

注意是任意位置,所以要枚举到100

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const int maxn = 110;
15 int n, a[maxn], ans = INT_MAX;
16 
17 int main() {
18     cin >> n;
19     for (int i = 1; i <= n; i++) cin >> a[i];
20     for (int i = 1; i <= 100; i++) {
21         int tmp = 0;
22         for (int j = 1; j <= n; j++) tmp += (a[j] - i) * (a[j] - i);
23         ans = min(ans, tmp);
24     }
25     cout << ans << endl;
26     return 0;
27 }
View Code

D:

题意是有n朵互不相同的花,从中选择至少1朵组成一束花,且花的朵数不等于a或b,有多少种选法。

显然C(n,1)+C(n,2)+...+C(n,n)=2^n-1, 答案就是2^n-1-C(n,a)-C(n,b)

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const ll mod = 1e9 + 7;
15 ll n, a, b;
16 
17 ll qp(ll x, ll b) {
18     ll ret = 1, base = x;
19     while (b) {
20         if (b & 1) ret = ret * base % mod;
21         base = base * base % mod;
22         b >>= 1;
23     }
24     return ret;
25 }
26 
27 ll C(ll n, ll m) {
28     if (!m) return 1LL;
29     if (m == 1) return n;
30     ll ret = 1, maxx = max(m, (n - m)), minn = min(m, (n - m));
31     for (ll i = n; i > maxx; i--) ret = ret * i % mod;
32     for (ll i = minn; i >= 1; i--) {
33         ll currInv = qp(i, mod - 2);
34         ret = ret * currInv % mod;
35     }
36     return ret;
37 }
38 
39 int main() {
40     cin >> n >> a >> b;
41     ll total = (qp(2, n) % mod - 1 % mod + mod) % mod;
42     ll c1 = C(n, a) % mod, c2 = C(n, b) % mod;
43     ll ans = ((total - c1 + mod) % mod - c2 + mod) % mod;
44     cout << ans << endl;
45     return 0;
46 }
View Code

E:

题意是有n间房子,一开始每间房子里各有一个人,定义一次移动:某人从房间i走到房间j,且i不等于j。现在已知房间个数n和已经发生的移动次数k。问:房间人数的可能情况有多少种?

ans=∑ C(n, i) * C(n - 1, n - i - 1), 1<=i<=k

i的意思是选定i间空房子。由于有n个人,这n个人会形成n-1个空隙,要在这n-1个空隙里插入n-i-1个隔板来形成n-i个非空房子。

C(n - 1, n - i - 1)可以O(n)预处理出来。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const int maxn = 2e5 + 10;
15 const ll mod = 1e9 + 7;
16 ll fac[maxn + 1], inv[maxn + 1], dp[maxn + 1], n, k;
17 
18 ll qp(ll x, ll y = mod - 2) {
19     ll ret = 1;
20     for (; y; y >>= 1, x = x * x % mod)
21         if (y & 1) ret = ret * x % mod;
22     return ret;
23 }
24 
25 ll C(int x, int y) {
26     return fac[x] * inv[y] % mod * inv[x - y] % mod;
27 }
28 
29 int main() {
30     fac[0] = fac[1] = 1;
31     for (int i = 1; i <= maxn; i++) fac[i] = fac[i - 1] * i % mod;
32     inv[maxn] = qp(fac[maxn]);
33     for (int i = maxn - 1; i >= 0; i--) inv[i] = inv[i + 1] * (i + 1) % mod;
34     cin >> n >> k;
35     k = min(n - 1, k);
36     ll ans = 1;
37     for (int i = 1; i <= n; i++) dp[i] = C(n - 1, i - 1);
38     for (int i = 1; i <= k; i++) ans = (C(n, i) * dp[n - i] % mod + ans) % mod;
39     cout << ans << endl;
40     return 0;
41 }
View Code

 

posted @ 2020-02-22 22:51  JHSeng  阅读(173)  评论(0编辑  收藏  举报