牛客练习赛76

牛客练习赛76

A 罚时上天

A 校园活动

搜索 dp 都行, 别忘特判就行

int f[N][9 * N], a[N], s;
 
int main() {
    scanf("%d", &n);
    rep (i, 1, n) scanf("%1d", a + i), s += a[i];
    if (!s) {
        return cout << n, 0;
    }
    rep (i, 1, n) rep (j, 0, s - 1) {
        if (f[i - 1][j] == -1) { f[i][j] = -1; continue; }
        f[i][j] = f[i - 1][j] + a[i];
        if (f[i][j] == j) f[i][j] = 0;
        else if (f[i][j] > j) f[i][j] = -1;
    }
    int c = -1;
    rep (i, 0, s - 1) if (!f[n][i]) { c = i; break; }
    cout << (c == -1 ? c : s / c);
    return 0;
}

B zzugzx (vs) Kurisu

推了40min 不会

C CG的通关秘籍

推到天荒地老, 最后才出

f[i][j] 表示 第 i 次放 j 的总贡献

f[i][j] = f[i- 1][1~m] + 2 * (m - i) + i - 1

没看明白? 写写看看

f[i][1] = f[i - 1][1~m] + 2 * (m - 1) + 0
f[i][2] = f[i - 1][1~m] + 2 * (m - 2) + 1
...
f[i][m] = f[i - 1][1~m] + 2 * 0 + m - 1

先抛开 f[i- 1][1~m], 看2 * (m - i) + i - 1

不就是两个等差数列吗, 一个等差 2, 一个等差 1, 都是从 0 开始, 有 m 项

即 3 * m * (m - 1) / 2

也就是每一次 f[i][1~m] = m * f[i - 1][1~m] + 3 * m * (m - 1) / 2

注意 f[2][1~m] = 3 * m * (m - 1) / 2

我们设 x = 3 * m * (m - 1) / 2;

(f[n][1~m] = m^{n - 2} * x + m^{n - 3} * x ... + x = x * (m - 1))

即 ans = 3 * m * (m - 1) / 2

原文地址:https://www.cnblogs.com/2aptx4869/p/14284685.html