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个的合法方案数。(好像还有其他的状态定义,也可以做)

  

posted @ 2014-01-06 09:26  hsuppr  阅读(255)  评论(0编辑  收藏  举报