Educational Codeforces Round 111 (Rated for Div. 2)_B. Maximum Cost Deletion

本文解析了如何利用MaximumCostDeletion算法解决题面中给定的连续数字删除问题,涉及思路转换、计数与策略优化。通过实例演示了b>=0时的操作和b<0时的区间合并策略,最终提供代码实现与详细解答。
摘要由CSDN通过智能技术生成

B. Maximum Cost Deletion

题目传送门:

题目传送门

题面:

在这里插入图片描述

题目大意:

给你 a , b , n a,b,n a,b,n,然后给你一个长度为 n n n的01串。
你只能选择连续的 l l l个相同数字一起删除,删除时候获得点数 a ∗ l + b a*l+b al+b,求全部删除获得最多点数为多少。

思路:

以后还是要想清楚再下手打。
一急躁就出问题。
首先好理解:
s u m = a ∗ ( l 1 + l 2 + . . l x ) + b ∗ x sum=a*(l_1+l_2+..l_x)+b*x sum=a(l1+l2+..lx)+bx
因为要全部删除,所以 l 1 + l 2 + . . l x = = n l_1+l_2+..l_x==n l1+l2+..lx==n,所以转化 s u m sum sum:
s u m = a ∗ n + b ∗ x sum=a*n+b*x sum=an+bx
x是操作数。

分两种情况:

  1. b ≥ 0 b≥0 b0,要操作数尽可能多,一个一个删;
  2. b < 0 b<0 b<0,要操作数尽可能少,记录0/1连续区间数,放到两个 v e c t o r vector vector里面。先根据 s i z e ( ) size() size()大小选择0或者1的区间进行逐个删除,最后操作就可以把已经提纯为仅含0或者1的字符串一次性删除。

情况2一开始没考虑清楚,居然把两个vector里面的都一段一段删除,很笨,白WA两次。

代码:

#include<bits/stdc++.h>

using namespace std;
const int maxn = 307;
int q[maxn];
int vis[maxn];
string str;

int main() {
    int T;
    cin >> T;
    while (T--) {
        int n, a, b;
        cin >> n >> a >> b;
        cin >> str;
        for (int i = 0; i < n; i++) {
            vis[i] = 1;
        }
      
        int cnt1 = 0;
        int cnt0 = 0;
        for (int i = 0; i < n; i++) {
            q[i] = str[i] - '0';
            if (q[i] == 1) cnt1++;
            else cnt0++;
//            cout<<q[i]<<" ";
            if (i == 0) continue;
            if (q[i] == q[i - 1]) {
                vis[i] = vis[i - 1] + 1;
            }
        }
//        cout<<endl;
//        for (int i = 0; i < n; i++)
//            cout << vis[i] << " ";
//        cout << endl;
        if (b >= 0) {
            cout << n * a + b * n << endl;
            continue;
        } else {
            vector<int> v1;
            vector<int> v0;
            for (int i = n - 1; i >= 0; i--) {
                if (i == n - 1) {
                    if (q[i] == 1)
                        v1.push_back(vis[i]);
                    if (q[i] == 0)
                        v0.push_back(vis[i]);
                    continue;
                }
                if (q[i] == 1 && vis[i] != vis[i + 1] - 1)
                    v1.push_back(vis[i]);
                if (q[i] == 0 && vis[i] != vis[i + 1] - 1)
                    v0.push_back(vis[i]);
            }
            int v00 = v0.size();
            int v11 = v1.size();
            int minn = min(v00, v11);
            int ans = n * a + b * minn + b;
            cout << ans << endl;

        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值