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

  

你可能感兴趣的:(codeforces)