动态规划基础篇(一)|| 更小的数

33 阅读1分钟

动态规划入门

蓝桥杯题目 3503 更小的数

题目分析

这道题目是求一个字符串序列的所有子串翻转后,统计数值比原来小的总情况

正常思维,按照子串长度,将该子串长度的子串翻转一遍,是O的3次方,但考虑到翻转过程中,可能存在重复计算的过程,比如当翻转最外侧发现无法比较之后,需要比较内侧,也就是长度为n-2的情况,这时就出现了重叠子问题现象

这时,我们可以采用动态规划的思想来优化它,首先设计DP状态:

最理想的办法,就是把DP[][]设置为子串的起始坐标和终止坐标,而当确定这两个坐标之后,就可以设置转移方程

当最外侧相同时,让dp[i][j]=dp[i+1][j-1]

值得注意的是,为了确保状态转移方程能顺利实现,必须保证dp[i+1][j-1]要在dp[i][j]的情况之前计算出来。

代码如下:

s = input()
dp = [ [0] *(len(s)+1) for i in range(len(s)+1)]
ans = 0

for i in range(len(s)):
    for j in range(0,len(s)-i):
        k = i+j
        if s[j]<s[k]:
            dp[j][k]=0
        elif s[k]<s[j]:
            dp[j][k]=1
        else:
            dp[j][k]=dp[j+1][k-1]
        if dp[j][k]==1:
            ans+=1
print(ans)
           

当采用pypy3的情况下,可以通过全部测试用例