美团笔试2022实习, 子串乘积正负分类

16 篇文章 0 订阅

题目

给你一个序列包含 n 个元素的序列 a1,a2,…,an (每个元素 ai要么是1 要么是-1)。这个序列中有多少子串(子串即连续子序列)的乘积为正,有多少子串的乘积为负。

输入

5
1 -1 1 -1 1

输出

7

乘积为正:

 [1]   [1]   [1]
  0     2     4
[-1,1,-1] 
1 2 3 
[1 -1 1 -1]   [-1 1 -1 1]
0 1 2 3       1 2 3 4
[1 -1 1 -1 1]
 1 2 3 4 5

这道题目是一个动态规划入门题。
我们定义状态:

  • f[i][0] 表示以 ai 结尾的乘积为正的子串个数;
  • f[i][1] 表示以 ai 结尾的乘积为负的子串个数。

可以得到状态转移方程为:

当 ai<0 时:

  • f[i][0]=f[i1][1]
  • f[i][1]=f[i1][0]+1

当 ai>0 时:

  • f[i][0]=f[i1][0]+1
  • f[i][1]=f[i1][1]

代码

def numberofpostive(n, a):
    f = [[0,0] for _ in range(n)]
    if a[0]:
        f[0][0] = 1
    else:
        f[0][1] = 1
    sum_number = f[0][0]
    for i in range(1, n):
        if a[i]==1:
            f[i][0] = f[i - 1][0] + 1
            f[i][1] = f[i - 1][1]
        else:
            f[i][0] = f[i - 1][1]
            f[i][1] = f[i - 1][0] + 1
        sum_number += f[i][0]
    return sum_number

n=5
a=[1,-1, 1 ,-1, 1]

m = numberofpostive(n,a)
print(m)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值