首页 > 其他 > 详细

Codeforces Round #612 (Div. 2)

时间:2020-01-21 14:03:45      阅读:63      评论:0      收藏:0      [点我收藏+]

C. Garland

直接无脑dp。

dp[i][j][0/1] 表示前 $i$ 个数里还剩 $j$ 个奇数可以用,最后一位的奇偶性的最小值。

然后由上一位转移就行了。

技术分享图片
#include <bits/stdc++.h>

const int N = 110, INF = 0x3f3f3f3f;
int dp[N][N / 2][2], p[N];

inline bool chkmin(int &a, int b) {
    return a > b ? a = b, 1 : 0;
}

inline bool chkmax(int &a, int b) {
    return a < b ? a = b, 1 : 0;
}

int main() {
    int n;
    scanf("%d", &n);
    const int cnt = (n + 1) / 2;
    for (int i = 1; i <= n; i++) 
        scanf("%d", p + i);
    memset(dp, 0x3f, sizeof(dp));
    if (p[1]) {
        int id = p[1] & 1;
        if (id) dp[1][cnt - 1][id] = 0;
        else dp[1][cnt][id] = 0;
    } else {
        dp[1][cnt - 1][1] = dp[1][cnt][0] = 0;
    }
    for (int i = 2; i <= n; i++) {
        for (int j = 0; j <= cnt; j++) {
            if (!p[i]) {
                chkmin(dp[i][j][1], std::min(dp[i - 1][j + 1][1], dp[i - 1][j + 1][0] + 1));
                chkmin(dp[i][j][0], std::min(dp[i - 1][j][1] + 1, dp[i - 1][j][0]));
            } else {
                if (p[i] & 1)
                    chkmin(dp[i][j][1], std::min(dp[i - 1][j + 1][1], dp[i - 1][j + 1][0] + 1));
                else 
                    chkmin(dp[i][j][0], std::min(dp[i - 1][j][1] + 1, dp[i - 1][j][0]));
            }
        }
    }
    printf("%d\n", std::min(dp[n][0][0], dp[n][0][1]));
    return 0;
}
View Code

 

D. Numbers on Tree

方案不存在当且仅当 $c_u \geq size_u$

dfs 这棵树,将子树的值插入到该节点上,两棵子树之间的值互不影响,那么可以排序后按大小关系重新赋值,再把该节点的值插入,其之后的值依次加 $1$ 即可。

技术分享图片
#include <bits/stdc++.h>
#define pii pair<int, int>
#define fi first
#define se second

const int N = 2e3 + 7;

std::vector<int> adj[N];
std::vector<std::pii> vec[N];
int n, c[N], root;
bool flag = 1;

void dfs(int u) {
    for (int i = 0, sz = adj[u].size(); i < sz; i++) {
        int v = adj[u][i];
        dfs(v);
        if (!flag) return;
        for (int j = 0; j < vec[v].size(); j++)
            vec[u].push_back(vec[v][j]);
        vec[v].clear();
    }
    if (c[u] > vec[u].size()) {
        flag = 0;
        return;
    }
    std::sort(vec[u].begin(), vec[u].end());
    for (int i = 0; i < vec[u].size(); i++)
        vec[u][i].fi = i + 1;
    vec[u].insert(vec[u].begin() + c[u], std::pii(c[u] + 1, u));
    for (int i = c[u] + 1; i < vec[u].size(); i++)
        vec[u][i].fi++;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        int p;
        scanf("%d%d", &p, c + i);
        if (!p) root = i;
        else adj[p].push_back(i);
    }
    dfs(root);
    if (!flag) {
        puts("NO");
    } else {
        for (int i = 0; i < n; i++)
            std::swap(vec[root][i].fi, vec[root][i].se);
        std::sort(vec[root].begin(), vec[root].end());
        puts("YES");
        for (int i = 0; i < n; i++)
            printf("%d%c", vec[root][i].se, " \n"[i == n - 1]);
    }
    return 0;
}
View Code

 

E1. Madhouse (Easy version)

询问一下 $[1...n]$,再询问一下 $[1...n-1]$,把所有后缀排个序,那么长度为 $1$ 的子串就相差第 $n$ 个字符,长度为 $2$ 的子串就相差第 $n-1$ 个字符和第 $n$ 个字符,这么依次做下去就行了

技术分享图片
#include <bits/stdc++.h>

void out(int l, int r) {
    std::cout << "? " << l << " " << r << std::endl;
    //std::cout.flush();
}

int cnt0[105], cnt1[105], dif[105];
char ans[105];

int main() {
    int n;
    std::cin >> n;
    if (n <= 3) {
        for (int i = 0; i < n; i++) {
            out(i + 1, i + 1);
            std::string temp;
            std::cin >> temp;
            ans[i] = temp[0];
        }
        std::cout << "! " << ans << std::endl;
        return 0;
    }
    out(1, n);
    for (int i = 0; i < n * (n + 1) / 2; i++) {
        std::string str;
        std::cin >> str;
        int len = str.length();
        for (int j = 0; j < len; j++)
            cnt0[len] += str[j] - a;
    }
    out(1, n - 1);
    for (int i = 0; i < n * (n - 1) / 2; i++) {
        std::string str;
        std::cin >> str;
        int len = str.length();
        for (int j = 0; j < len; j++)
            cnt1[len] += str[j] - a;
    }
    for (int i = 1; i <= n; i++) {
        dif[i] = cnt0[i] - cnt1[i];
        ans[n - i] = dif[i] - dif[i - 1] + a;
    }
    std::cout << "! " << ans << std::endl;
    return 0;
}
View Code

 

E2. Madhouse (Hard version)

Codeforces Round #612 (Div. 2)

原文:https://www.cnblogs.com/Mrzdtz220/p/12221047.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!