abc 137 Count 1‘s 【经典思维】

给定一串1、0数字,可以选择任意区间翻转,0会变成1,1会变成0。问区间的取值种类有多少。

思维:

这个题也是匹配问题,因为 0 1 是相消的, 怎么体现相消呢,一个置1,一个置-1呗。再继续思考,对于每个区间如果数 > 0 意味着1多,翻过来总体的值就变小,< 0 意味着0多,反过来总体的值就变大。找区间的最大最小值。

再数学化一点:

假设 a 是一个原串的 1 的数量,b 是选择的区间的 0 的数量,c 是选择的区间的 1 的数量,则翻转后串的价值是 a+b-c
a 的数量是确定的,变的是 b-c 的数量,所以我们只需要知道 b-c 的值可能有多少种即可。所以考虑将字符 1 的位置看做数值 1,将字符 0 的位置看做数值-1这样使得区间数字和就是 b-c。

现在问题变成给定一个数组,问区间和存在多少种不同的值
由于数值只有 1 和-1,所以我们可以求最大区间子段和与最小区间
子段和的差值即可

码风一:能加就加原则,不能加就赋值

for (int i = 0; i < n; i ++ ) {
    if(sum < 0) sum = a[i];
    else sum += a[i];
    mx = max(mx, sum);
}

码风二:tourist的思维,R(答案上界,一定是由某一个pref减去他前面的最小值),L(答案下界),    mx(维护的是当前i之前的所有的最小值),mi。 注意,这套“模板”mx和mi的更新是在r和l之后的。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

int main(){
    //std::ios::sync_with_stdio(false);
    //std::cin.tie(nullptr);
    int n;
    cin >> n;
    std::vector<int> a(n);
    for (int i = 0; i < n; i ++ ) {
        cin >> a[i];
        a[i] = (a[i] == 1 ? 1 : -1);
    }   
    vector<int> pref(n + 1, 0);
    for (int i = 0; i < n; i ++ ) {
        pref[i + 1] = pref[i] + a[i];
    }
    int L = 0;
    int R = 0;
    int mi = 0;
    int mx = 0;
    for (int i = 1; i <= n; i ++ )
    {
        R = max(R, pref[i] - mi);
        L = min(L, pref[i] - mx);
        mx = max(mx, pref[i]);
        mi = min(mi, pref[i]);
    }
    cout << R - L + 1 << '\n';
    return 0;
}

再数学化一点:

假设 a 是一个原串的 1 的数量,b 是选择的区间的 0 的数量,c 是选择的区间的 1 的数量,则翻转后串的价值是 a+b-c
a 的数量是确定的,变的是 b-c 的数量,所以我们只需要知道 b-c 的值可能有多少种即可。所以考虑将字符 1 的位置看做数值 1,将字符 0 的位置看做数值-1这样使得区间数字和就是 b-c。

现在问题变成给定一个数组,问区间和存在多少种不同的值
由于数值只有 1 和-1,所以我们可以求最大区间子段和与最小区间
子段和的差值即可

再数学化一点:

假设 a 是一个原串的 1 的数量,b 是选择的区间的 0 的数量,c 是选择的区间的 1 的数量,则翻转后串的价值是 a+b-c
a 的数量是确定的,变的是 b-c 的数量,所以我们只需要知道 b-c 的值可能有多少种即可。所以考虑将字符 1 的位置看做数值 1,将字符 0 的位置看做数值-1这样使得区间数字和就是 b-c。

现在问题变成给定一个数组,问区间和存在多少种不同的值
由于数值只有 1 和-1,所以我们可以求最大区间子段和与最小区间
子段和的差值即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值