Codeforces 367
A. Sereja and Algorithm
水题不解释。
B. Sereja ans Anagrams
模p同余的为一组,随便搞。
C. Sereja and the Arrangement of Numbers
我还以为是找规律。。。
把每个数当成一个点。就有一个图。让后求欧拉路什么的。
D. Sereja and Sets
这个思路感觉很巧妙(可能是我太弱了),我们对于每一段连续的d,找到不包含它们的所有集合,这些集合的子集一定不可行。
见代码。
/* * Problem: D. Sereja and Sets * Author: Shun Yao */ #include <string.h> #include <stdlib.h> #include <limits.h> #include <assert.h> #include <stdio.h> #include <ctype.h> #include <math.h> #include <time.h> #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <deque> #include <string> #include <vector> #include <bitset> #include <utility> #include <iomanip> #include <numeric> #include <sstream> #include <iostream> #include <algorithm> #include <functional> //using namespace std; int n, m, d, bad[1 << 21], s[100010], cnt[25]; int main(/*int argc, char **argv*/) { int i, j, k, l, tmp, ans; scanf("%d%d%d", &n, &m, &d); for (i = 0; i < m; ++i) { scanf("%d", &j); for (k = 0; k < j; ++k) { scanf("%d", &l); s[l - 1] = i; } } memset(bad, 0, sizeof bad); for (i = 0; i < n; ++i) { if (i >= d) --cnt[s[i - d]]; ++cnt[s[i]]; if (i >= d - 1) { tmp = 0; for (j = 0; j < m; ++j) if (!cnt[j]) tmp += 1 << j; bad[tmp] = 1; } } ans = 21; for (i = (1 << m) - 1; i >= 0; --i) { if (!bad[i]) { k = i; l = 0; while (k) { ++l; k -= k & -k; } ans = std::min(ans, l); } else { k = i; while (k) { l = k & -k; bad[i - l] = 1; k -= l; } } } printf("%d", ans); fclose(stdin); fclose(stdout); return 0; }
E. Sereja and Intervals
问题是求n个互不包含的区间且其中一个区间的左端是x的方案数。(原题n个区间排列也算不同方案,为了方便思考我们可以考虑排列算相同方案,然后让结果成以n的阶乘。
f[i][j][k]代表目前到i,有左端点j个,右端点k个的合法方案数。(好像还有其他的状态定义,也可以做)
作者:HSUPPR
出处:http://www.cnblogs.com/hsuppr/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接,否则保留追究法律责任的权利。