2022年第十三届蓝桥杯 python B组 第H题 技能升级

这道题刚开始以为挺简单的,直接暴力,每次选最大的,发现只能过极少的案例,后来想了很久,才想到用单调栈加二分,如果有大神知道更好的做法,恳请留言。

###########基础知识

1.单调栈

2.二分法

#################

对于直接暴力的解法其时间复杂度肯定是O(n*m)的,后来我想到用二分法对技能表进行从大到小的排序,每次选下标【0】的元素来用,用完后威力减去对应值(Ai-Bi),再用二分法插到相应位置,时间复杂度为O(m*logn),发现还是慢了!。

再后来我想到其实技能表在一开始排好序的时候 其要加那些威力就已经定了!!

#############解释

案例:n=3,m=6.arr=[[10,5],[9,2],[8,1]],

最终加威力顺序:【10,9,8,7,7,6】

####################

所以做了很多的无用二分操作,所以我建了一个大小为m的单调栈,对于单调栈的插入还是要用二分,具体如下

对于每一个输入的技能,其可提供的所有可能的种类有(Ai//Bi+1)个,我会将这所有的种类全部插入单调栈,(##如【10,3】会提供 【10】,【7】,【4】,【1】) 。细节:如果一个技能提供的第一个种类被插在了z位置,那么后面的种类将会在z~l而不是0~l

##############解释

案例:n=3,m=6.arr=[[10,5],[9,2],[8,1]],                          d(单调栈):[]

1,目前已输入【10,5】,生成种类【10】【5】【0】         d=[10,5,0]

2,目前已输入【9,2】,生成种类【9】【7】【5】【3】【2】【0】        d=[10,9,7,5,5,3]

3,目前已输入【8,1】,生成种类【8】【7】【6】【5】【4】.....             d=[10,9,8,7,7,6]

最终结果为sum(d)=47

#############

代码如下:

#############################函数部分
def Binary_insert(a,loca):#二分插入,(新元素,loca>-1就不从0开头)
    global arr,sum,m
    l=len(arr)

    q=loca if loca>-1 else 0
    p=l-1
    while q<=p:
        mi=(q+p)//2
        if arr[mi]>a:#缩头
            q=mi+1
        else:#缩尾
            p=mi-1
    arr.insert(q,a)
    sum+=arr[q]
    if len(arr)>m:
        sum -= arr[m]
        del arr[m]

    return  q

def Extract(a):#榨取所有种类
    loca=-1
    while a[0]>0:
        loca=Binary_insert(a[0],loca)
        a[0]-=a[1]

# ###########################输入部分
n,m=map(int,input().split())
sum=0#最终值
arr=[]#单调栈
for i in range(n):
    a,b=map(int,input().split())
    Extract([a,b])
# ##############################输出部分
print(sum)

你可能感兴趣的:(蓝桥杯,算法,蓝桥杯)