codeforces 苏珊的珍珠

本文介绍了一个使用C++编写的名为Pearls的类,用于解决一个关于平衡整数向量的问题,通过计算和调整部分元素来保持特定比例的平衡。主要关注get_sum和set方法的使用以及work方法中的线性时间复杂度求解过程。
摘要由CSDN通过智能技术生成
#include <bits/stdc++.h>
using namespace std;

class Sum
{
private:
    vector<int> sum;

public:
    Sum()
    = default;

    void set(vector<int> &val)
    {
        sum.clear();
        if (val.empty())
            return;
        sum.push_back(val[0]);
        int sz = val.size();
        for (int i = 1; i < sz; ++i)
            sum.push_back(sum[i - 1] + val[i]);
    }

    inline int get_sum(int i)
    {
        return i >= 0 ? sum[min<int>(i, sum.size())] : 0;
    }

    // sum[l..r]
    inline int get_sum(int l, int r)
    {
        return get_sum(r) - get_sum(l - 1);
    }

    void print()
    {
        for (auto x : sum)
            cout << x << " ";
        cout << endl;
    }
};

class Pearls
{
private:
    int total_cnt;
    int hang_cnt;
    int k;
    vector<int> weight;
    vector<int> cost;
    Sum w;
    Sum c;
    struct Ans
    {
        int l;
        int r;
        int cost;
        bool valid;
        void update(int l0, int r0, int cost0)
        {
            if (valid)
            {
                if (cost0 > cost)
                {
                    l = l0;
                    r = r0;
                    cost = cost0;
                }
            }
            else
            {
                l = l0;
                r = r0;
                cost = cost0;
                valid = true;
            }
        }
        void print() const
        {
            cout << l + r << " " << cost << endl;
            string s(r,'H');
            string ss(l,'T');
            cout<<s<<ss<<endl;
        }
    }ans;

public:
    void init()
    {
        cin >> total_cnt >> hang_cnt >> k;
        weight.resize(total_cnt + 1);
        cost.resize(total_cnt + 1);
        weight[0] = cost[0] = 0;
        for (int i = 1; i <= total_cnt; ++i)
        {
            cin >> weight[i] >> cost[i];
        }
        w.set(weight);
        c.set(cost);
    }
    void work()
    {
        int w_h;
        int w_t;
        int table_end;
        for (int end = total_cnt; end >= hang_cnt; --end)
        {
            table_end = end - hang_cnt;
            w_h = w.get_sum(table_end + 1, end);
            w_t = w.get_sum(1, table_end);
            if (w_h > k * w_t)
            {
                // 前面一颗珠子不少仍旧无法实现这个状态的平衡,则无法实现。
                // 因为end更小的无法绕过这一end的状况。所以更小的end也无需考虑。
                break;
            }
            int l = 1;             // is ok 可以维持平衡
            int r = table_end + 1; // is not ok 不可以维持平衡
            while (r - l > 1)
            {
                int m = l + (r - l) / 2;
                w_t = w.get_sum(m, table_end);
                if (w_h <= k * w_t)
                { // m is ok
                    l = m;
                }
                else
                {
                    r = m;
                }
            }
            ans.update(l-1, total_cnt - end, c.get_sum(1, l - 1) + c.get_sum(end + 1, total_cnt));
        }
        ans.print();
    }
};

int main()
{
    Pearls *p = new Pearls();
    p->init();
    p->work();
    delete p;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值