Codeforces Round #191 (Div. 2) A. Flipping Game

题目链接:https://codeforces.com/problemset/problem/327/A

题目大意:给定一个长度为n的0/1序列,选取一段区间,将区间内的0改为1,1改为0,问这么一次操作后序列中1的个数最多为多少?

题解:

原题中数据范围很小,暴力即可。

当数据范围更大时的解法O(n):

假设我们任意选取一段区间,在这段区间中,1将变为0,这意味着整个序列中1的个数将减少1;0将变为1,这意味着整个序列中1的个数将增加1。

我们可以将1视为-1, 0视为1,将题目转化为求新的序列的最大子段和。

 1 #include<iostream>
 2 #include<vector>
 3 #include<map>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstdio>
 7 #include<cmath>
 8 #include<string>
 9 #include<set>
10 #include<complex>
11 #include<cstdio>
12 #include<cstring>
13 #include<stack>
14 #include<iomanip>
15 #include<bitset>
16 #include<typeinfo>
17 #include<random>
18 #include<unordered_map>
19 #include<unordered_set>
20 using namespace std;
21 
22 const int maxn = 1e6 + 10;
23 
24 int n, ans = 0, cnt_one = 0;
25 int a[maxn], b[maxn], dp[maxn];
26 
27 int main(){
28     scanf("%d", &n);
29     for(int i = 1; i <= n; i++){
30         scanf("%d", &a[i]);
31         if(a[i] == 1){
32             b[i] = -1;
33             cnt_one++;
34         }
35         else b[i] = 1;
36     }
37     memset(dp, 0, sizeof(dp));
38     for(int i = 1; i <= n; i++){
39         dp[i] = max(dp[i - 1] + b[i], b[i]);
40         ans = max(ans, dp[i]);
41     }
42     if(ans == 0) ans = -1;
43     printf("%d\n", cnt_one + ans);
44     return 0;
45 }

猜你喜欢

转载自www.cnblogs.com/mrzhangziheng/p/11614564.html