Problem:


Score : 700 points

Problem Statement

N cells are arranged in a row.
Some of them may contain tokens.
You are given a string s that consists of 0s and 1s.
If the i-th character of s is 1, the i-th cell (from left) contains a token.
Otherwise, it doesn't contain a token.

Snuke wants to perform the following operation as many times as possible.
In each operation, he chooses three consecutive cells.
Let's call the cells X, Y, Z from left to right.
In order for the operation to be valid, both X and Z must contain tokens and Y must not contain a token.
Then, he removes these two tokens and puts a new token on Y.

How many operations can he perform if he performs operations in the optimal way?

Constraints

1 \leq N \leq 500,000

|s| = N

Each character in s is either 0 or 1.

Input

Input is given from Standard Input in the following format:

N
s

Output

Print the answer.

Sample Input 1

7
1010101

Sample Output 1

2

For example, he can perform two operations in the following way:

Perform an operation on the last three cells. Now the string that represents tokens becomes 1010010.

Perform an operation on the first three cells. Now the string that represents tokens becomes 0100010.

Note that the choice of operations matters.
For example, if he chooses three cells in the middle first, he can perform no more operations.

Sample Input 2

50
10101000010011011110001001111110000101010111100110

Sample Output 2

10



Sample input:
7
1010101


Sample output:
2

Submission status: Wrong Answer

Solution code:
n = int(input())
s = input()

ss = []
cnt = 0
for c in s:
    if c == '1':
        cnt += 1
    else:
        if cnt > 0:
            ss.append(cnt)
            cnt = 0
        ss.append(cnt)
if cnt > 0:
    ss.append(cnt)
def solve(seq):
    l = len(seq)
    if not seq:
        return 0
    while seq[-1] == 0:
        seq.pop()

    dp = [0]*(l+1)
    for i in range(l):
        if i+1 <= l:
            dp[i+1] = max(dp[i+1], dp[i])
        if i+2 <= l:
            dp[i+2] = max(dp[i+2], dp[i] + max(seq[i], seq[i+1]))
        if i+3 <= l and seq[i+1] >= 2:
            dp[i+3] = max(dp[i+3], dp[i] + seq[i] + seq[i+2])
    return max(dp)
idx = 0
cur = []
ans = 0
while idx < len(ss):
    if idx+1 < len(ss) and ss[idx] == ss[idx+1] == 0:
        idx += 2
        ans += solve(cur)
        cur = []
    elif not cur and ss[idx] == 0:
        idx += 1
    else:
        if ss[idx]:
            cur.append(ss[idx])
        idx += 1
if cur:
    ans += solve(cur)
print(ans)

Submission status: Wrong Answer

Solution code:
n = int(input())
s = input()

ss = []
cnt = 0
for c in s:
    if c == '1':
        cnt += 1
    else:
        if cnt > 0:
            ss.append(cnt)
            cnt = 0
        ss.append(cnt)
if cnt > 0:
    ss.append(cnt)
def solve(seq):
    l = len(seq)
    if not seq:
        return 0
    while seq[-1] == 0:
        seq.pop()

    dp = [0]*(l+1)
    for i in range(l):
        if i+1 <= l:
            dp[i+1] = max(dp[i+1], dp[i])
        if i+2 <= l:
            dp[i+2] = max(dp[i+2], dp[i] + max(seq[i], seq[i+1]))
    return max(dp)
idx = 0
cur = []
ans = 0
while idx < len(ss):
    if idx+1 < len(ss) and ss[idx] == ss[idx+1] == 0:
        idx += 2
        ans += solve(cur)
        cur = []
    elif not cur and ss[idx] == 0:
        idx += 1
    else:
        if ss[idx]:
            cur.append(ss[idx])
        idx += 1
if cur:
    ans += solve(cur)
print(ans)

Submission status: Wrong Answer

Solution code:
import re

rep_zeros = re.compile('0{2,}')
rep_ioioi = re.compile('((?:10)+1)')

n = input()
s = input().strip('0')
ans = 0

for ps in re.split(rep_zeros, s):
    fs = re.split(rep_ioioi, ps)
    if len(fs) == 1:
        continue
    ls = list(map(len, fs))
    for l in ls[1::2]:
        ans += (l + 1) // 4
    mls = ls[0::2]
    ans += sum(mls) - min(mls)
print(ans)

Submission status: Wrong Answer

Solution code:
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**15
mod = 10**9+7

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()

def main():
    n = I()
    s = [_=='1' for _ in S()]
    r = 0
    for i in range(2,n-3):
        if s[i-2] and s[i-1] and not s[i] and s[i+1] and s[i+2]:
            r += 1
            s[i-1] = False
            s[i] = True
            s[i+1] = False

    a = []
    c = s[0]
    t = 1
    for i in range(1,n):
        if c == s[i]:
            t += 1
        else:
            a.append((c,t))
            c = s[i]
            t = 1
    a.append((c,t))
    if a[0][0] == 0:
        a = a[1:]

    c = 0
    m = inf
    i = 0
    while i < len(a):
        if a[i][0] == 0:
            i += 1
            continue
        t = a[i][1]
        m = a[i][1]
        c = 1
        j = i+1
        while j < len(a)-1:
            if a[j][1] != 1:
                break
            k = a[j+1][1]
            t += k
            c += 1
            if (j-i-1) % 4 == 0 and m > k:
                m = k
            j += 2
        if c > 1:
            if c % 2 == 0:
                r += t - c//2
            else:
                r += t - c//2 - m
            a = a[j:]
            i = -1
        i += 1

    return r


print(main())

Submission status: Wrong Answer

Solution code:
N=int(input())
s=list(map(int,list(input())))

count=0


for i in range(1,len(s)-2):
    if s[i-1]==1 and s[i+1]==1 and s[i]==0 and s[i+2]==1:
        s[i+1]=0
        s[i]=1
        s[i-1]=0
        count+=1

s=list(reversed(s))
for i in range(1,len(s)-2):
    if s[i-1]==1 and s[i+1]==1 and s[i]==0 and s[i+2]==1:
        s[i+1]=0
        s[i]=1
        s[i-1]=0
        count+=1

s=list(reversed(s))

for i in range(1,len(s)-1):
    if s[i-1]==1 and s[i+1]==1 and s[i]==0:
        s[i+1]=0
        s[i]=1
        s[i-1]=0
        count+=1

s=list(reversed(s))

for i in range(1,len(s)-1):
    if s[i-1]==1 and s[i+1]==1 and s[i]==0:
        s[i+1]=0
        s[i]=1
        s[i-1]=0
        count+=1


print(count)

Submission status: Wrong Answer

Solution code:
def pt(x):
    n = 0
    dp = [0]*(len(x))
    if len(x) < 2: return 0
    dp[1] = max(x[0],x[1])
    for i in range(2,len(x)):
        dp[i] = max(dp[i-2]+max(x[i-1],x[i]),dp[i-3]+max(x[i-2],x[i-1],x[i]))
    return dp[len(x)-1]

n = int(input())
s = input()
ret = 0
prev = 0
tmp1 = []
tmp_ctr = 0
for i in range(n):
    if s[i] == "0":
        if prev == "0":
            ret += pt(tmp1)
            tmp1 = []
        else:
            tmp1.append(tmp_ctr)
            tmp_ctr = 0
    else:
        tmp_ctr += 1
    prev = s[i]

if tmp_ctr != 0:tmp1.append(tmp_ctr)
ret += pt(tmp1)
print(ret)

Submission status: Wrong Answer

Solution code:
import re

rep_zeros = re.compile('00+')
rep_ioioi = re.compile('((?:10)+1)')

n = input()
s = input().strip()
ans = 0

for ps in re.split(rep_zeros, s):
    fs = re.split(rep_ioioi, ps)
    if len(fs) == 1:
        continue
    ls = list(map(len, fs))
    for l in ls[1::2]:
        ans += (l + 1) // 4
    mls = ls[0::2]
    ans += sum(mls) - min(mls)
print(ans)

Submission status: Wrong Answer

Solution code:
N = int(input())
S = [c for c in input()]

i = 0
count = 0

while i < N - 2:
    if S[i] == '1' and S[i + 1] == '0' and S[i + 2] == '1':
        S[i] = '0'
        S[i + 1] = '1'
        S[i + 2] = '0'
        count += 1
    i += 1

print(count)

Submission status: Wrong Answer

Solution code:
n = int(input())
s = input()

ss = []
cnt = 0
for c in s:
    if c == '1':
        cnt += 1
    else:
        if cnt > 0:
            ss.append(cnt)
            cnt = 0
        ss.append(cnt)
if cnt > 0:
    ss.append(cnt)
def solve(seq):
    if not seq:
        return 0
    while seq[-1] == 0:
        seq.pop()
    return max(sum(seq[1::2]), sum(seq[2::2]), sum(seq[-2::-2]), sum(seq[-3::-2]))

idx = 0
cur = []
ans = 0
while idx < len(ss):
    if idx+1 < len(ss) and ss[idx] == ss[idx+1] == 0:
        idx += 2
        ans += solve(cur)
        cur = []
    elif not cur and ss[idx] == 0:
        idx += 1
    else:
        if ss[idx]:
            cur.append(ss[idx])
        idx += 1
if cur:
    ans += solve(cur)
print(ans)

Submission status: Wrong Answer

Solution code:
# -*- coding: utf-8 -*-
import re
result = 0

N = int(input())
s = input()
text = s.replace("10", "a").replace("a0", "100")
typea = re.findall("a1+", text)

for a in typea:
    result += len(a)-1

result += re.sub("a1+", "d", text).replace("aa", "b").count("b")

print(result)

Submission status: Wrong Answer

Solution code:
def pt(x):
    n = 0
    ret = 0
    ret2 = 0
    while n < len(x)-2:
        ret += max(x[n], x[n+1])
        ret2 += max(x[n+1] , x[n+2])
        n += 2
    if n < len(x)-1:
        ret += max(x[n] , x[n+1])
    return max(ret,ret2)

n = int(input())
s = input()
ret = 0
prev = 0
tmp1 = []
tmp_ctr = 0
for i in range(n):
    if s[i] == "0":
        if prev == "0":
            ret += pt(tmp1)
            tmp1 = []
        else:
            tmp1.append(tmp_ctr)
            tmp_ctr = 0
    else:
        tmp_ctr += 1
    prev = s[i]

if tmp_ctr != 0:tmp1.append(tmp_ctr)
ret += pt(tmp1)
print(ret)

Submission status: Wrong Answer

Solution code:
N=int(input())
s=list(map(int,list(input())))

count=0

for i in range(1,len(s)-2):
    if s[i-1]==1 and s[i+1]==1 and s[i]==0 and s[i+2]==1:
        s[i+1]=0
        s[i]=1
        s[i-1]=0
        count+=1

for i in range(1,len(s)-1):
    if s[i-1]==1 and s[i+1]==1 and s[i]==0:
        s[i+1]=0
        s[i]=1
        count+=1

print(count)

Submission status: Wrong Answer

Solution code:
# -*- coding: utf-8 -*-
import re
result = 0

N = int(input())
s = input()
text = s.replace("10", "a").replace("a0", "100")
typea = re.findall("a1+", text)

for a in typea:
    result += len(a)-1

result += re.sub("a1+", "", text).replace("aa", "b").count("b")

print(result)

Submission status: Wrong Answer

Solution code:
s=input()
s=input()
ones=0# 0:0000 1:1111 2:1110111
res=0
for c in s:
 if ones==0 and c=="0":
  continue
 elif ones==0 and c=="1":
  ones=1
  numone=1
  numoneR=0
  continue
 elif ones==1 and c=="1":
  numone+=1
  continue
 elif ones==1 and c=="0":
  ones=2
  continue
 elif ones==2 and c=="1":
  numoneR+=1
  continue
 elif ones==2 and c=="0":
  ones=0
  if numoneR==0:
   continue
  res+=max(numone,numoneR)
  continue
if(ones==2):
  res+=max(numone,numoneR)
print(res)

Submission status: Wrong Answer

Solution code:
s=input()
s=input()
ones=0# 0:0000 1:1111 2:1110111
res=0
for c in s:
 if ones==0 and c=="0":
  continue
 elif ones==0 and c=="1":
  ones=1
  numone=1
  numoneR=0
  continue
 elif ones==1 and c=="1":
  numone+=1
  continue
 elif ones==1 and c=="0":
  ones=2
  continue
 elif ones==2 and c=="1":
  numoneR+=1
  continue
 elif ones==2 and c=="0":
  ones=0
  if numoneR==0:
   continue
  res+=max(numone,numoneR)
  continue
print(res)

Submission status: Wrong Answer

Solution code:
N = input()
s = input()
cnt = 0

for idx in range(len(s) - 2):
    a = s[idx] + s[idx + 1] + s[idx + 2]
    if a == '101':
        s = s[:idx] + '010' + s[idx + 3:]
        cnt += 1

print(cnt)

Submission status: Wrong Answer

Solution code:
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**15
mod = 10**9+7

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()

def main():
    n = I()
    s = [_=='1' for _ in S()]
    r = 0
    for i in range(n-2):
        if s[i] and not s[i+1] and s[i+2]:
            if i < n-5 and not s[i+3] and s[i+4] and s[i+5]:
                s[i+2] = False
                s[i+3] = True
                s[i+4] = False
            else:
                s[i+1] = True
                s[i+2] = False
            r += 1
    for i in range(n-1,1,-1):
        if s[i] and not s[i-1] and s[i-2]:
            s[i-1] = True
            s[i-2] = False
            r += 1

    return r


print(main())

Submission status: Wrong Answer

Solution code:
N=int(input())
s=list(map(int,list(input())))

count=0
for i in range(1,N-1):
    if s[i-1]==1 and s[i+1]==1 and s[i]==0:
        s[i+1]=0
        s[i]=1
        count+=1


print(count)

Submission status: Time Limit Exceeded

Solution code:
rec=0
def tikan(src,cnt):
 if not "101" in src:
  return cnt
 kekkalist=[]
 for i  in range(len(src)-2):
  if src[i:i+3]=="101":
   kekkalist.append(tikan(src[0:i]+"010"+src[i+3:],cnt+1))
 return max(kekkalist)
raw_input()
s=raw_input()
record=tikan(s,0)
print record

Submission status: Time Limit Exceeded

Solution code:
l = int(input())
s = input()

def BFS(start,l):
    queue = [(0,start)]
    seen = set()

    index = 0
    while index < len(queue):
        x = 0
        y = 1
        z = 2
        current = queue[index]
        # Slide through the string for 101
        while z < l:
            p = current[1][:x] + "010" + current[1][z+1:]
            if current[1][x] == "1" and current[1][y] == "0" and current[1][z] == "1" and p not in seen:
                queue.append((current[0]+1,p))
                
            z += 1
            y += 1
            x += 1
            
        seen.add(current[1])
        index += 1

    queue = sorted(queue)
    return queue[-1]

print(BFS(s,l)[0])

Submission status: Accepted

Solution code:
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce


sys.setrecursionlimit(2147483647)
INF = 10 ** 13
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS(): return sys.stdin.readline().rstrip().split()
def S(): return sys.stdin.readline().rstrip()
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 10 ** 9 + 7


n = I()
s = list(S())
ans = 0
one_cnt = 0
z_cnt = 0
dp = []
flg = 0
for i in range(n):
    if s[i] == "1":
        one_cnt += 1
        z_cnt = 0
        if flg:
            if dp:
                ans += max(dp)
                dp = []
            flg = 0
        if i == n - 1 or s[i + 1] == "0":
            # 手付かず、左端だけ消した、右端だけ残す、全て消した。
            if dp:
                if one_cnt >= 2:
                    ndp = [max(dp), max(dp[0] + pre, dp[1] + pre - 1, dp[2] + 1),
                           max(dp[0], dp[1], dp[2]) + one_cnt - 1,
                           max(dp[0], dp[1], dp[2]) + one_cnt]
                else:
                    ndp = [-INF, -INF, max(dp),
                           max(dp[0] + pre, dp[1] + pre - 1, dp[2] + 1)]
                dp = ndp
            else:
                dp = [0, -INF, -INF, -INF]
            pre = one_cnt
    else:
        z_cnt += 1
        one_cnt = 0
        if z_cnt >= 2:
            flg = 1

if dp:
    ans += max(dp)

print(ans)

Submission status: Accepted

Solution code:
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce


sys.setrecursionlimit(2147483647)
INF = 10 ** 13
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS(): return sys.stdin.readline().rstrip().split()
def S(): return sys.stdin.readline().rstrip()
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 10 ** 9 + 7


n = I()
s = list(S())
ans = 0
one_cnt = 0
z_cnt = 0
dp = []
flg = 0
for i in range(n):
    if s[i] == "1":
        one_cnt += 1
        z_cnt = 0
        if flg:
            if dp:
                ans += max(dp)
                dp = []
            flg = 0
        if i == n - 1 or s[i + 1] == "0":
            # 手付かず、左端だけ消した、右端だけ残す、全て消した。
            if dp:
                if one_cnt > 2:
                    ndp = [max(dp), max(dp[0] + pre, dp[1] + pre - 1, dp[2] + 1),
                           max(dp[0], dp[1], dp[2]) + one_cnt - 1,
                           max(dp[0], dp[1], dp[2]) + one_cnt]
                elif one_cnt == 2:
                    ndp = [max(dp), max(dp[0] + pre, dp[1] + pre - 1, dp[2] + 1),
                           max(dp[0] + pre, dp[1] + pre - 1, dp[2] + 1),
                           max(dp[0], dp[1], dp[2]) + 2]
                else:
                    ndp = [-INF, -INF, max(dp),
                           max(dp[0] + pre, dp[1] + pre - 1, dp[2] + 1)]
                dp = ndp
            else:
                dp = [0, -INF, -INF, -INF]
            pre = one_cnt
    else:
        z_cnt += 1
        one_cnt = 0
        if z_cnt >= 2:
            flg = 1

if dp:
    ans += max(dp)

print(ans)

Submission status: Accepted

Solution code:
import sys

readline = sys.stdin.readline
ns = lambda: readline().rstrip()
ni = lambda: int(readline().rstrip())
nm = lambda: map(int, readline().split())
nl = lambda: list(map(int, readline().split()))


def solve():
    n = ni()
    s = ns()
    l = list()
    for i in range(1, n-1):
        if s[i] == '0':
            li = ri = i
            while li > 0 and s[li - 1] == '1':
                li -= 1
            while ri + 1 < n and s[ri + 1] == '1':
                ri += 1
            if li != i != ri:
                l.append((i-1, i+2))
                for j in range(li, i-1):
                    l.append((j, i+2))
                for j in range(i+2, ri+1):
                    l.append((i-1, j+1))
    l.sort()
    l.sort(key = lambda x: x[1])
    # print(l)
    m = len(l)
    dp = [0]*(n+1)
    idx = 0
    for i in range(n+1):
        dp[i] = max(dp[i], dp[i-1])
        while idx < m and l[idx][0] == i:
            x, y = l[idx]
            dp[y] = max(dp[y], dp[x] + y - x - 2)
            idx += 1
    # print(dp)
    print(dp[n])
    return

solve()

# T = ni()
# for _ in range(T):
#     solve()

Submission status: Accepted

Solution code:
import sys
readline = sys.stdin.readline

INF = 10**9+7
class Segtree:
    def __init__(self, A, intv, initialize = True, segf = max):
        self.N = len(A)
        self.N0 = 2**(self.N-1).bit_length()
        self.intv = intv
        self.segf = segf
        if initialize:
            self.data = [intv]*self.N0 + A + [intv]*(self.N0 - self.N)
            for i in range(self.N0-1, 0, -1):
                self.data[i] = self.segf(self.data[2*i], self.data[2*i+1]) 
        else:
            self.data = [intv]*(2*self.N0)
        
    def update(self, k, x):
        k += self.N0
        self.data[k] = x
        while k > 0 :
            k = k >> 1
            self.data[k] = self.segf(self.data[2*k], self.data[2*k+1])
    
    def query(self, l, r):
        L, R = l+self.N0, r+self.N0
        s = self.intv
        while L < R:
            if R & 1:
                R -= 1
                s = self.segf(s, self.data[R])
            if L & 1:
                s = self.segf(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s
    
    def binsearch(self, l, r, check, reverse = False):
        L, R = l+self.N0, r+self.N0
        SL, SR = [], []
        while L < R:
            if R & 1:
                R -= 1
                SR.append(R)
            if L & 1:
                SL.append(L)
                L += 1
            L >>= 1
            R >>= 1
        
        if reverse:
            for idx in (SR + SL[::-1]):
                if check(self.data[idx]):
                    break
            else:
                return -1
            while idx < self.N0:
                if check(self.data[2*idx+1]):
                    idx = 2*idx + 1
                else:
                    idx = 2*idx
            return idx - self.N0
        else:
            pre = self.data[l+self.N0]
            for idx in (SL + SR[::-1]):
                if not check(self.segf(pre, self.data[idx])):
                    pre = self.segf(pre, self.data[idx])
                else:
                    break
            else:
                return -1
            while idx < self.N0:
                if check(self.segf(pre, self.data[2*idx])):
                    idx = 2*idx
                else:
                    pre = self.segf(pre, self.data[2*idx])
                    idx = 2*idx + 1
            return idx - self.N0

N = int(readline())
S = [0]+list(map(int, readline().strip()))

leftone = [None]*(N+1)
left = None
for i in range(N+1):
    if S[i] == 1:
        if left is None:
            left = i
        leftone[i] = left
    else:
        left = None

T = Segtree([None]*(N+1), -INF, initialize = False)
dp = [0]*(N+1)
T.update(0, 0)
T.update(1, -1)
T.update(2, -2)
for i in range(3, N+1):
    res = dp[i-1]
    if S[i] == 1:
        if S[i-1] == 0 and S[i-2] == 1:
            left = leftone[i-2]
            res = max(res, T.query(left-1, i-2)+i-2)
        if leftone[i] > 2 and S[leftone[i]-1] == 0 and S[leftone[i]-2] == 1:
            res = max(res, dp[leftone[i]-3] + i-leftone[i]+2-1)
    dp[i] = res
    T.update(i, dp[i]-i)
print(dp[-1])

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

N = int(readline())
S = readline().rstrip().decode('utf-8')

def solve_partial(S):
    INF = 10**18
    """
    ・Sは1から始まり、1で終わる
    ・Sは00を含まない
    ・したがって、Sは1,01に分解可能
    ・残る最小個数を調べるdp。これは、1, 101111,111101 の3種を数えることと同じ
    ・a, b0cccc, dddd0e として、「現在の1がどれであるか -> 最小個数」でdp
    ・個数はa,b,eのときに数える
    """
    S = S.replace('01','2')
    a,b,c,d,e = 1,1,INF,0,INF
    for x in S[1:]:
        ace = min(a,c,e)
        if x == '1':
            a2 = ace+1
            c2 = c
            d2 = ace if ace<d else d
            e2 = INF
        else:
            a2 = ace+1
            c2 = a
            d2 = ace
            e2 = d+1
        a,c,d,e = a2,c2,d2,e2
    return len(S)-min(a,c,e)

answer = 0
for x in S.split('00'):
    x = x.strip('0')
    if x:
        answer += solve_partial(x)

print(answer)

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

N = int(readline())
S = readline().rstrip().decode('utf-8')

def solve_partial(S):
    INF = 10**18
    """
    ・Sは1から始まり、1で終わる
    ・Sは00を含まない
    ・したがって、Sは1,01に分解可能
    ・残る最小個数を調べるdp。これは、1, 101111,111101 の3種を数えることと同じ
    ・a, b0cccc, dddd0e として、「現在の1がどれであるか -> 最小個数」でdp
    ・個数はa,b,eのときに数える
    """
    S = S.replace('01','2')
    a,b,c,d,e = 1,1,INF,0,INF
    for x in S[1:]:
        if x == '1':
            a2 = min(a,c,e)+1
            c2 = c
            d2 = min(a,c,d,e)
            e2 = INF
        else:
            a2 = min(a,c,e)+1
            c2 = a
            d2 = min(a,c,e)
            e2 = d+1
        a,c,d,e = a2,c2,d2,e2
    return len(S)-min(a,c,e)

answer = 0
for x in S.split('00'):
    x = x.strip('0')
    if x:
        answer += solve_partial(x)

print(answer)

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

N = int(readline())
S = readline().rstrip().decode('utf-8')

def solve_partial(S):
    INF = 10**18
    """
    ・Sは1から始まり、1で終わる
    ・Sは00を含まない
    ・したがって、Sは1,01に分解可能
    ・残る最小個数を調べるdp。これは、1, 101111,111101 の3種を数えることと同じ
    ・a, b0cccc, dddd0e として、「現在の1がどれであるか -> 最小個数」でdp
    ・個数はa,b,eのときに数える
    """
    S = S.replace('01','2')
    a,b,c,d,e = 1,1,INF,0,INF
    for x in S[1:]:
        if x == '1':
            a2 = min(a,c,e)+1
            b2 = min(a,c,e)+1
            c2 = c
            d2 = min(a,c,d,e)
            e2 = INF
        else:
            a2 = min(a,c,e)+1
            b2 = min(a,c,e)+1
            c2 = b
            d2 = min(a,c,e)
            e2 = d+1
        a,b,c,d,e = a2,b2,c2,d2,e2
    return len(S)-min(a,c,e)

answer = 0
for x in S.split('00'):
    x = x.strip('0')
    if x:
        answer += solve_partial(x)

print(answer)

Submission status: Accepted

Solution code:
#!/usr/bin/python3

import re


n = input()
s = input()


sb = re.sub(r'^0+', '', s)
sb = re.sub(r'0+$', '', sb)
sb = re.sub(r'00+', '-', sb)

tlist = sb.split('-')
counts_list = []

for t in tlist:
    counts = []
    tt = t.split('0')
    for ttt in tt:
        counts.append(len(ttt))
    counts_list.append(counts)

ans = 0

for counts in counts_list:

    len_counts = len(counts)
    sum_all = sum_decr = sum_one = sum_zero = 0

    for i in range(len_counts - 1):

        new_sum_all = new_sum_decr = new_sum_one = new_sum_zero = 0

        # do nothing
        new_sum_all = max(sum_all, sum_decr, sum_one, sum_zero)

        # go to left all
        new_sum_decr = max(new_sum_decr, sum_all + counts[i])
        new_sum_decr = max(new_sum_decr, sum_decr + counts[i] - 1)
        new_sum_decr = max(new_sum_decr, sum_one + 1)

        # go to right all - 1
        new_sum_one = max(new_sum_one, sum_all + counts[i+1] - 1)
        if (counts[i] >= 2):
            new_sum_one = max(new_sum_one, sum_decr + counts[i+1] - 1)
        new_sum_one = max(new_sum_one, sum_one + counts[i+1] - 1)

        # go to right all
        new_sum_zero = max(new_sum_zero, sum_all + counts[i+1])
        if (counts[i] >= 2):
            new_sum_zero = max(new_sum_zero, sum_decr + counts[i+1])
        new_sum_zero = max(new_sum_zero, sum_one + counts[i+1])

        sum_all = new_sum_all
        sum_decr = new_sum_decr
        sum_one = new_sum_one
        sum_zero = new_sum_zero

    ans += max(sum_all, sum_decr, sum_one, sum_zero)


print(ans)

Submission status: Accepted

Solution code:
#!/usr/bin/python3

import re
from pprint import pprint


n = input()
s = input()

sb = re.sub(r'^0+', '', s)
sb = re.sub(r'0+$', '', sb)
sb = re.sub(r'00+', '-', sb)
#pprint('---- sb = %s' % (sb, ))

tlist = sb.split('-')
#pprint('---- tlist = %s' % (tlist, ))

counts_list = []
for t in tlist:
    counts = []
    tt = t.split('0')
    for ttt in tt:
        counts.append(len(ttt))
    counts_list.append(counts)
#pprint('---- counts_list = %s' % (counts_list, ))

ans = 0

for counts in counts_list:

    len_counts = len(counts)
    sum_all = sum_decr = sum_one = sum_zero = 0

    for i in range(len_counts - 1):

        new_sum_all = new_sum_decr = new_sum_one = new_sum_zero = 0

        # do nothing
        new_sum_all = max(sum_all, sum_decr, sum_one, sum_zero)

        # go to left all
        new_sum_decr = max(new_sum_decr, sum_all + counts[i])
        new_sum_decr = max(new_sum_decr, sum_decr + counts[i] - 1)
        new_sum_decr = max(new_sum_decr, sum_one + 1)

        # go to right all - 1
        new_sum_one = max(new_sum_one, sum_all + counts[i+1] - 1)
        if (counts[i] >= 2):
            new_sum_one = max(new_sum_one, sum_decr + counts[i+1] - 1)
        new_sum_one = max(new_sum_one, sum_one + counts[i+1] - 1)

        # go to right all
        new_sum_zero = max(new_sum_zero, sum_all + counts[i+1])
        if (counts[i] >= 2):
            new_sum_zero = max(new_sum_zero, sum_decr + counts[i+1])
        new_sum_zero = max(new_sum_zero, sum_one + counts[i+1])

        sum_all = new_sum_all
        sum_decr = new_sum_decr
        sum_one = new_sum_one
        sum_zero = new_sum_zero

        #pprint('  sum_all=%d sum_decr=%d sum_one=%d sum_zero=%d' %
        #       (sum_all, sum_decr, sum_one, sum_zero))

    #pprint('---- incr = %d' % max(sum_all, sum_decr, sum_one, sum_zero))

    ans += max(sum_all, sum_decr, sum_one, sum_zero)


print(ans)

Submission status: Accepted

Solution code:
N = int(input())
s = input()

# 「連続する1の数」のリストに変換する
s = s[s.find('1'):] # 先頭の'0'を取り除く
while s.count('000'):
    s = s.replace('000', '00')
cs = list(map(len, s.split('0')))

# dp[i]: i番目の「連続する1」への各処理（操作に使わない／左の１つだけ使う／右の１つを残して使う／全て使う）
#        に対して、現時点での操作回数の最大値
dp = [[-float('inf')] * 4 for i in range(len(cs))]
dp[0][0] = 0
for i in range(1, len(cs)):
    if cs[i] == 0:
        dp[i][3] = max(dp[i - 1])
        continue

    # 使わない
    dp[i][0] = max(dp[i - 1])
    # 全て使う
    dp[i][3] = max(dp[i - 1][0] + max(cs[i - 1], cs[i]), \
                   dp[i - 1][1] + max(cs[i - 1] - 1, cs[i]), \
                   dp[i - 1][2] + cs[i], \
                   dp[i - 1][3])
    if cs[i] >= 2:
        # 左の１つだけ使う
        dp[i][1] = max(dp[i - 1][0] + cs[i - 1], \
                       dp[i - 1][1] + cs[i - 1] - 1, \
                       dp[i - 1][2] + 1, \
                       dp[i - 1][3])
        # 右の１つを残して使う
        dp[i][2] = max(dp[i - 1][0] + max(cs[i - 1], cs[i] - 1), \
                       dp[i - 1][1] + max(cs[i - 1] - 1, cs[i] - 1), \
                       dp[i - 1][2] + cs[i] - 1, \
                       dp[i - 1][3])

print(max(dp[-1]))

Submission status: Accepted

Solution code:
# D
N = int(input())
s = list(map(int, list(input())))

        
def calc_add(temp_list):
    if len(temp_list) <= 1:
        return 0
    else:
        res = 0
        # use 101 for left
        dp_l = [0]*len(temp_list)
        # use 101 for right 
        dp_r = [0]*len(temp_list)
        # do not use 101
        dp_c = [0]*len(temp_list)
        for i in range(len(temp_list) - 1):
            if temp_list[i] > 1:
                dp_l[i+1] = max(dp_l[i] + temp_list[i] - 1, dp_c[i] + temp_list[i])
            else:
                dp_l[i+1] = dp_c[i] + temp_list[i]
            if temp_list[i] > 1:
                dp_r[i+1] = max(dp_l[i] + temp_list[i+1], dp_c[i] + temp_list[i+1], dp_r[i] + temp_list[i+1] - 1)
            else:
                dp_r[i+1] = dp_c[i] + temp_list[i+1]
            dp_c[i+1] = max(dp_l[i], dp_r[i], dp_c[i])
        
        return max(dp_l[-1], dp_r[-1], dp_c[-1])
    

cont0 = 1
cont00 = 1
temp_list = []
res = 0

for i in range(N):
    if s[i] == 1:
        if cont0 == 1:
            temp_list.append(1)
            cont0 = 0
            cont00 = 0
        else:
            temp_list[-1] += 1
    else:
        if cont00 == 1:
            pass
        elif cont0 == 1:
            cont00 = 1
            res += calc_add(temp_list)
            temp_list = []
        else:
            cont0 = 1
            
    if i == N - 1:
        res += calc_add(temp_list)
        
print(res)