AT_arc137_b [ARC137B] Count 1's 题解
解题思路
假设我们能得到的最大的分数是 \(maxx\),最小的分数是 \(minx\),我们的可能的种类就是 \(maxx-minx+1\),因为这一区域的分数都是可以做到的。而之所以如此,是因为每增加或减少一个数字,就只会改变一个 \(0\) 或 \(1\),所以这一区间的分数都可以拿到。
于是,问题就成为了让我们求最大分数和最小分数。
我们再用 \(b\) 数组记录当前改变会对分数产生的影响,\(maxn\) 代表当时所能得到的最大分数,\(minn\) 同理。
所以,当:
-
\(a_i\) 等于 \(1\) 时,我们将 \(b_i\) 设为 \(-1\)。因为将其反转后分数会减一。
-
\(a_i\) 等于 \(0\) 时,我们将 \(b_i\) 设为 \(1\)。因为将其反转后分数会加一。
此时,我们再给 \(b\) 取前缀和,这时数组 \(b\) 就表示从开头到当前节点的所有改变造成的影响。
我们就可以从一枚举,每次更新各个变量的数值。
代码
#include<bits/stdc++.h>
using namespace std;
int a[300005],b[300005];
int main(){
int n,maxx=0,minx=0,maxn=0,minn=0;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],b[i]=b[i-1]+(a[i]==0?1:-1);
for(int i=1;i<=n;i++){
maxx=max(maxx,b[i]-minn),
minx=min(minx,b[i]-maxn);
maxn=max(maxn,b[i]),
minn=min(minn,b[i]);
}
cout<<maxx-minx+1;
return 0;
}

浙公网安备 33010602011771号