【蓝桥Python每日一练】————前缀和模板(线性DP)

 大家好,我是爱分享的小蓝,欢迎交流指正~ 


线性DP-前缀和模板

遇到区间求和先问自己3个问题,如果都能回答,那前缀和就被你拿捏了~

第一个问题:前缀和是个啥?

顾名思义,前缀和就是前缀的元素求和,一个区间的总数和sum(a[l:r])

第二个问题:为什么要学前缀和?

因为它就像一个火箭,装上它的程序速度直接起飞!时间复杂度从O(n*m)降到O(n)。

第三个问题:那前缀和怎么学习呢?

很简单,先理解原理,再背背模板,最后刷题巩固就掌握了。(╹ڡ╹ )

#线性DP-前缀和模板
for i in range(1,n):
   dp[i]=dp[i-1]+a[i]
print(dp[r]-dp[l-1])

'''
参数说明:
n个数,区间左端点l,区间右端点r,
权值列表a,前缀和列表dp

测试样例:
n      1   2   3  
a= [0, 7,  5,  6]
dp=[0, 7, 12, 18]
'''

线性DP-大学里的树木要维护⭐

传送锚点

【蓝桥Python每日一练】————前缀和模板(线性DP)_第1张图片

【蓝桥Python每日一练】————前缀和模板(线性DP)_第2张图片

   样例输入

10 3
7 5 6 4 2 5 0 8 5 3
1 5
2 6
3 7

   样例输出

24
22
17

思路点拨

解决这种问题一般有两种方法:暴力枚举和动态规划。

建议先写一版暴力枚举,能过一半的测试案例。

然后再写动态规划版的代码,过所有的测试案例,得满分。

1、输入:先输入题目里的一堆参数 n ,m ,a ,l , r。

2、计算:再构建前缀和列表dp,计算出所有的前缀和保存起来。

3、输出:最后输出两个区间端点对应的前缀和之差。

代码详解 

#暴力枚举-大学里的树木要维护
n,m=map(int,input().split())
a=list(map(int,input().split()))
for i in range(m):
    l,r=map(int,input().split())
    print(sum(a[l-1:r]))
#线性DP-大学里的树木要维护
n,m=map(int,input().split())          #n棵树 m个区间
a=[0]+list(map(int,input().split()))  #维护开销
dp=[0 for i in range(n+1)]            #前缀和列表
for i in range(1,n+1):                #遍历1~n
    dp[i]=dp[i-1]+a[i]                #计算前缀和
for i in range(m):                    #m次询问
    l,r=map(int,input().split())      #区间左右
    print(dp[r]-dp[l-1])              #两和作差
print(dp)   
'''
样例输入:
10 3
7 5 6 4 2 5 0 8 5 3
1 5
2 6
3 7

测试样例:
n      1   2   3   4   5   6   7   8   9  10
a= [0, 7,  5,  6,  4,  2,  5,  0,  8,  5, 3 ]
dp=[0, 7, 12, 18, 22, 24, 29, 29, 37, 42, 45]
'''

  读码上万行,下键如有神,撸起袖子加油干!

你可能感兴趣的:(备战蓝桥杯,python,蓝桥杯,算法,动态规划)