「Codeforces 510D」Fox And Jumping 题解

主要思路

欲覆盖整个直线,那么只需要让这些步数能合成一个\(1\)即可。那么根据 Bézout 定理,有\(ax + by = \gcd(a, b)\),那么我们可以用这个做 DP:不停地合成新的\(\gcd\)来找最小代价。

代码

// CF510D.cpp
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 330;

int li[MAX_N], ci[MAX_N], n;
map<int, int> ump;
map<int, int>::iterator it;

int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &li[i]);
    for (int i = 1; i <= n; i++)
        scanf("%d", &ci[i]);
    for (int i = 1; i <= n; i++)
    {
        int tmp = ump[li[i]];
        if (tmp == 0)
            ump[li[i]] = ci[i];
        else
            ump[li[i]] = min(tmp, ci[i]);
        for (it = ump.begin(); it != ump.end(); it++)
        {
            int di = gcd(it->first, li[i]);
            tmp = ump[di];
            if (tmp == 0)
                ump[di] = it->second + ci[i];
            else
                ump[di] = min(tmp, ci[i] + it->second);
        }
    }
    printf("%d", ump[1] ? ump[1] : -1);
    return 0;
}

Codeforce 708C:Centroids 题解

Up & Down 的 \(\Theta(n)\) DP

我们发现,这道题其实就是要判断把子树中,最大不超过\(\frac{n}{2}\)的子树接到根部上,子树是否仍能保持\(> \frac{n}{2}\)。

我们按照第一遍的做法做一次 DP,记录当前子树最大和次大值。

然后考虑得出 Up 的 DP 值:首先从父亲转移,然后再用最大值和次小值(不能在同一子树内,这就是次小值存在的意义)来更新当前的 Up 的 DP 值。

Continue reading →

牛客 CSP-S 提高组赛前集训营 1 – 解题报告

A – 仓鼠的石子游戏

诶嘿题。画了几张图发现只有\(1\)的情况先手必胜,所以考虑多轮交换先后手即可。

// A.cpp
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 1e3 + 200, table[8] = {0, 0, 1, 1, 1, 1, 1, 1};

int T, n, ai[MAX_N];

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", &ai[i]);
        bool flag = false;
        for (int i = 1; i <= n; i++)
            flag ^= (ai[i] == 1);
        printf(flag ? "rabbit\n" : "hamster\n");
    }
    return 0;
}

Continue reading →

Codeforces 1247D:Power Products 题解

主要思路

真就您🐎乱搞嘛。

我们可以考虑在怎样的一个情况下才能把一个数称之为\(x^k\):自然是所有质因数的次数都为\(k\)的倍数,即\(b_i \equiv 0 \pmod k\)。那么,我们可以考虑把一个数分解,表示成质因数的幂:只不过这个次数要模个\(k\)。然后,进行哈希,放到unordered_map中。做哈希的时候做两份,一份是自身,还有一份是凑足完全\(k\)次方的哈希。

但是比较麻烦的是,如果我们搞所有质数,那么会超时。所以,这个时候要给所有质数标号,然后算出质数之间编号差来乘上其哈希幂。

Continue reading →

P3615:如厕计划题解

主要思路

还是要勤思考,说不定是能想出来的。

考虑对这个序列做后缀和,女性代表-1,男性代表+1,然后发现只要保证后缀和一直大于\(-2\)即可。那么,我们可以维护每一段的后缀和,然后维护最大后缀和。

计算答案的时候需要知道要抬升多少才能让整个折线不会碰到\(-2\)的线,找到最大抬升的值就行了(这样都能合法)。

Continue reading →