【蓝桥模板】——遇到区间求和问题如何快速解决?(前缀和模板)

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


线性DP-前缀和模板

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

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

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

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

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

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

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

#线性DP-前缀和模板
for i in range(1,n+1):
   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-大学里的树木要维护⭐

🚀传送锚点

   样例输入

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=[0]+list(map(int,input().split()))
for i in range(m):
    l,r=map(int,input().split())
    print(sum(a[l:r+1]))
#线性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])              #两和作差  
'''
样例输入:
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]
'''

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

  • 22
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蓝刷题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值