• [CF1411D] Grime Zoo


    [CF1411D] Grime Zoo - 贪心,组合

    Description

    给定由字符 0,1,? 组成的字符串 s 和参数 x,y,需要在所有字符为 ? 的位置填入 0 或者 1。这个字符串的价值为子序列 01 的数量乘以 x 加上 10 的数量乘以 y。求字符串价值的最小值。

    Solution

    存在一个分割点,分割点之前的 ? 全部填一个值,后面的全部填另一个值

    在 x>y 时,我们希望多点 10,所以前面的 ? 填 1,后面的 ? 填 0,反过来同理

    现在我们去枚举分割点,关键是怎样计算答案

    假设分割点为 i

    考虑前 0 后 1 的情况

    额外的 01 个数,等于前面的 0 的个数乘以后面的 ? 个数,加上前面的 ? 个数乘以后面的 1 个数

    考虑前 1 后 0 的情况

    额外的 10 个数,等于前面的 1 的个数乘以后面的 ? 个数,加上前面的 ? 个数乘以后面的 0 个数

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        string str;
        int x, y;
        cin >> str >> x >> y;
        int n = str.length();
    
        int c01 = 0, c10 = 0;
        int c0 = 0, c1 = 0;
    
        vector<int> a0(n + 2), a1(n + 2), b(n + 2), a(n + 2);
        for (int i = 1; i <= n; i++)
        {
            a0[i] = str[i - 1] == '0';
            a1[i] = str[i - 1] == '1';
            b[i] = str[i - 1] == '?';
            a0[i] += a0[i - 1];
            a1[i] += a1[i - 1];
            b[i] += b[i - 1];
            if (str[i - 1] == '0')
                c0++;
            if (str[i - 1] == '1')
                c1++;
            if (str[i - 1] == '1')
                c01 += c0;
            if (str[i - 1] == '0')
                c10 += c1;
        }
    
        auto f0 = [&](int l, int r) -> int { return a0[r] - a0[l - 1]; };
        auto f1 = [&](int l, int r) -> int { return a1[r] - a1[l - 1]; };
        auto fb = [&](int l, int r) -> int { return b[r] - b[l - 1]; };
    
        int tans = 0;
    
        int ans = 1e18;
    
        for (int i = 1; i <= n; i++)
        {
            if (str[i - 1] == '0' || str[i - 1] == '?')
                a[i] = 0, tans += y * f1(1, i - 1);
            else
                a[i] = 1, tans += x * (f0(1, i - 1) + fb(1, i - 1));
        }
    
        ans = min(ans, tans);
        for (int i = 1; i <= n; i++)
            if (str[i - 1] == '?')
            {
                a[i] = 1;
                tans -= y * (f1(1, i - 1) + fb(1, i - 1)) + x * (f1(i + 1, n));
                tans += x * (f0(1, i - 1)) + y * (f0(i + 1, n) + fb(i + 1, n));
                ans = min(ans, tans);
            }
    
        tans = 0;
    
        for (int i = 1; i <= n; i++)
        {
            if (str[i - 1] == '0')
                a[i] = 0, tans += y * (f1(1, i - 1) + fb(1, i - 1));
            else
                a[i] = 1, tans += x * (f0(1, i - 1));
        }
        ans = min(ans, tans);
    
        for (int i = 1; i <= n; i++)
            if (str[i - 1] == '?')
            {
                a[i] = 0;
                tans -= x * (f0(1, i - 1) + fb(1, i - 1)) + y * (f0(i + 1, n));
                tans += y * (f1(1, i - 1)) + x * (f1(i + 1, n) + fb(i + 1, n));
                ans = min(ans, tans);
            }
    
        cout << ans << endl;
    }
    
  • 相关阅读:
    free online Twitter video downloader All In One
    Game Development Essential Terms All In One
    Offscreen Canvas All In One
    前端性能优化系列之 Service Workers 实战教程 All In One
    前端性能优化系列之 Web Workers 实战教程 All In One
    河南美食阿利茄汁面 All In One
    free online Youtube video downloader All In One
    Leetcode 2264. 字符串中最大的 3 位相同数字(可以,已解决)
    多分类任务中不同隐藏层层数对实验结果的影响(使用GPU)
    Pytorch 损失函数总结
  • 原文地址:https://www.cnblogs.com/mollnn/p/14428390.html
Copyright © 2020-2023  润新知