# DP题组

Median Sum

1 <= n <= 2000

 1 #include <cstdio>
2 #include <bitset>
3
4 const int N = 2010;
5
6 std::bitset<N * N> bt;
7
8 int a[N];
9
10 int main() {
11     int n, tot = 0;
12     scanf("%d", &n);
13     for(int i = 1; i <= n; i++) {
14         scanf("%d", &a[i]);
15     }
16     for(int i = 1; i <= n; i++) {
17         bt |= (bt << a[i]);
18         bt[a[i]] = 1;
19         tot += a[i];
20     }
21     tot = (tot + 1) >> 1;
22     while(bt[tot] == 0) {
23         tot++;
24     }
25     printf("%d", tot);
26     return 0;
27 }
AC代码

No Need

1 <= n, k <= 5000

no need 的一定是连续最小的一段，证明如下：

check函数用上一题的思想，对于 x ，只要去掉 x 的集合和没有在[k - x, k)之间的，x 即为 no need

 1 #include <cstdio>
2 #include <bitset>
3 #include <algorithm>
4
5 const int N = 5010;
6
7 std::bitset<N> bt;
8
9 int n, a[N], k;
10
11 inline bool check(int x) {
12     if(a[x] >= k) {
13         return 1;
14     }
15     bt.reset();
16     for(int i = 1; i <= n; i++) {
17         if(i == x) {
18             continue;
19         }
20         if(a[i] > N - 1) {
21             break;
22         }
23         bt |= (bt << a[i]);
24         bt.set(a[i]);
25     }
26     for(int i = k - a[x]; i < k; i++) {
27         if(bt[i]) {
28             return 1;
29         }
30     }
31     return 0;
32 }
33
34 int main() {
35     scanf("%d%d", &n, &k);
36     for(int i = 1; i <= n; i++) {
37         scanf("%d", &a[i]);
38     }
39     std::sort(a + 1, a + n + 1);
40     int l = 1, r = n, mid;
41     while(l < r) {
42         mid = (l + r + 1) >> 1;
43         if(check(mid)) {
44             r = mid - 1;
45         }
46         else {
47             l = mid;
48         }
49     }
50     if(r == 1 && check(1)) {
51         r = 0;
52     }
53     printf("%d", r);
54     return 0;
55 }
AC代码

すぬけ君の塗り絵 / Snuke's Coloring

1 <= m, n <= 10 ^ 9

0 <= k <= 10 ^ 5

 1 #include <cstdio>
2 #include <map>
3 #include <algorithm>
4
5 typedef long long LL;
6
7 const int N = 100010;
8
9 struct A {
10     int x, y;
11     A(int x = 0, int y = 0) {
12         this->x = x;
13         this->y = y;
14     }
15     bool operator < (const A &d) const {
16         if(x == d.x) {
17             return y < d.y;
18         }
19         return x < d.x;
20     }
21     bool operator == (const A &d) const {
22         return x == d.x && y == d.y;
23     }
24 }a[N * 9];
25
26 std::map<A, int> mp;
27
28 int ans[10];
29
30 int main() {
31     int m, n, k;
32     scanf("%d%d%d", &n, &m, &k);
33     for(int i = 1, x, y; i <= k; i++) {
34         scanf("%d%d", &x, &y);
35         for(int j = 0; j < 3; j++) {
36             for(int k = 0; k < 3; k++) {
37                 if(x + j > n || y + k > m || x + j < 3 || y + k < 3) {
38                     continue;
39                 }
40                 mp[A(x + j, y + k)]++;
41             }
42         }
43     }
44     std::map<A, int>::iterator it = mp.begin();
45     int tot = 0;
46     for(; it != mp.end(); it++) {
47         tot++;
48         ans[it->second]++;
49     }
50     printf("%lld\n", 1ll * (m - 2) * (n - 2) - 1ll * tot);
51     for(int i = 1; i <= 9; i++) {
52         printf("%d\n", ans[i]);
53     }
54     return 0;
55 }
AC代码

Largest Smallest Cyclic Shift

 1 #include <cstdio>
2 #include <set>
3 #include <iostream>
4
5 using std::string;
6
7 std::multiset<string> s;
8
9 int main() {
10     int n;
11     scanf("%d", &n);
12     for(int i = 1; i <= n; i++) {
13         s.insert("a");
14     }
15     scanf("%d", &n);
16     for(int i = 1; i <= n; i++) {
17         s.insert("b");
18     }
19     scanf("%d", &n);
20     for(int i = 1; i <= n; i++) {
21         s.insert("c");
22     }
23     while(s.size() > 1) {
24         string a = *s.begin();
25         string b = *(--s.end());
26         s.erase(s.begin());
27         s.erase(--s.end());
28         s.insert((string)(a + b));
29     }
30     std::cout << *s.begin();
31     return 0;
32 }
AC代码

Popping Balls

posted @ 2018-07-11 15:06  garage  阅读(...)  评论(...编辑  收藏