跳转至

Codeforces Round 1010 (Div. 2, Unrated)

比赛链接: https://codeforces.com/contest/2082

B

哎哎,这个看着稍微有点难受啊,因为我瞎搞也对了。

如果想要结果更大,那先用向下取整再用向上取整是更好的。结果更小先用向上取整。。

void ChatGptDeepSeek()
{
    int x, n, m;
    cin >> x >> n >> m;
    n = min(35, n), m = min(35, m);
    vector<vector<int>> dp1(n + 1, vector<int>(m + 1, 0));
    vector<vector<int>> dp2(n + 1, vector<int>(m + 1, 1e9 + 1));
    dp1[0][0] = x, dp2[0][0] = x;
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= m; j++) {
            if (i) {
                dp1[i][j] = max(dp1[i][j], dp1[i - 1][j] / 2);
                dp2[i][j] = min(dp2[i][j], dp2[i - 1][j] / 2);
            }
            if (j) {
                dp1[i][j] = max(dp1[i][j], (dp1[i][j - 1] & 1) + dp1[i][j - 1] / 2);
                dp2[i][j] = min(dp2[i][j], (dp2[i][j - 1] & 1) + dp2[i][j - 1] / 2);
            }
            // cerr << dp1[i][j] << '\n';
        }
    // for (int i = 0; i <= n; i++)
    //     for (int j = 0; j <= m; j++)
    //         cerr << dp1[i][j] << " \n"[j == m];
    // cerr << '\n';
    cout << dp2[n][m] << " " << dp1[n][m] << '\n';
}

C

只有最高位的下一位可以进位的时候,才会多用一次操作。

using ll = long long;
constexpr int mod = 1e9 + 7;

ll ksm(ll a, ll b)
{
    ll res = 1;
    while (b) {
        if (b & 1)
            res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
ll inv = ksm(2, mod - 2);
void ChatGptDeepSeek()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    if (n == 1) {
        cout << "0\n";
        return;
    }
    vector<ll> f(n);
    reverse(s.begin(), s.end());
    if (s[0] == '1')
        f[0] = inv;
    for (int i = 1; i < n; i++) {
        if (s[i] == '1')
            f[i] = (1 - f[i - 1]) * inv % mod + f[i - 1];
        else
            f[i] = inv * f[i - 1] % mod;
        f[i] = (f[i] + mod) % mod;
    }
    cout << (n - 1 + f[n - 2]) % mod << '\n';
}

所以其实向下取整操作,只有在前面全为1时,才会使位不变,但是这样会使除最高位全为0,这样永远不会再触发第二次了。

所以想要多一次操作,那必然就是第二位能产生进位的概率。

11111
10000
1000
100
10
1