小美定义一个 01 串的权值为:每次操作选择一位取反,使得相邻字符都不相等的最小操作次数。
例如,"10001"的权值是 1,因为只需要修改一次:对第三个字符取反即可。
现在小美拿到了一个 01 串,她希望你求出所有非空连续子串的权值之和,你能帮帮她吗?
一个仅包含'0'和'1'的字符串,长度不超过 2000。
所有非空子串的权值和。
10001
8
长度为 2 的子串中,有 2 个"00"的权值是 1。长度为 3 的 3 个子串权值都是 1。长度为 4 的 2 个子串权值都是 1。长度为 5 的 1 个子串权值是 1。总权值之和为 2+3+2+1=8
st = list(map(int, input().strip())) dp = [list(st), [int(i!=1) for i in st]] res = 0 while len(dp[0])>1: dp = [dp[1][:-1], dp[0][:-1]] for idx, i in enumerate(st[-len(dp[0]):]): dp[int(i==0)][idx] += 1 res += sum([min(i, j) for i, j in zip(dp[0], dp[1])]) print(res)
st = list(map(int, input().strip())) dp = [st, list(map(int, map(lambda x: x==0, st)))] addtiton = dp.copy() res = 0 def dp_add(dp1, dp2): return [[x + y for x, y in zip(row1, row2)] for row1, row2 in zip(dp1, dp2)] while len(dp[0])>1: addtiton = [addtiton[0][1:], addtiton[1][1:]] dp = dp_add([dp[1][:-1], dp[0][:-1]], addtiton) res += sum([min(i, j) for i, j in zip(dp[0], dp[1])]) print(res)