【蓝桥杯题集python】

背包模板


#https://www.acwing.com/problem/content/2/
n,v1=map(int,input().split())
k=[[0 for i in range(v1+1)] for j in range(n+1)]
v=[0]
w=[0]
for i in range(n):
    a,b=map(int,input().split())
    v.append(a)
    w.append(b)
for i in range(1,n+1):
    for j in range(1,v1+1):
        if j<v[i]:
            k[i][j]=k[i-1][j]
        else:
            k[i][j]=max(k[i-1][j],k[i-1][j-v[i]]+w[i])
print(k[n][v1])

滚动数组法

n,v1=map(int,input().split())
k=[0]*(v1+10)
v=[0]
w=[0]
for i in range(n):
    a,b=map(int,input().split())
    v.append(a)
    w.append(b)
for i in range(1,n+1):
    for j in range(v1,-1,-1):
        if j<v[i]:
            break
        k[j]=max(k[j],k[j-v[i]]+w[i])
print(k[v1])

完全背包问题

# https://www.acwing.com/problem/content/3/
n,v1=map(int,input().split())
k=[[0 for i in range(v1+1)] for j in range(n+1)]
v=[0]
w=[0]
for i in range(n):
    a,b=map(int,input().split())
    v.append(a)
    w.append(b)
for i in range(1,n+1):
    for j in range(1,v1+1):
        if j<v[i]:
            k[i][j]=k[i-1][j]
        else: 
            k[i][j]=max(k[i-1][j],k[i][j-v[i]]+w[i]) //同一个物品可以选多次,所以是第i个
print(k[n][v1])

多重背包问题 I

# https://www.acwing.com/problem/content/4/
n, v1 = map(int, input().split())
v = [0] * (n + 10)
w = [0] * (n + 10)
s = [0] * (n + 10)
dp = [0] * (v1 + 10)
for i in range(1, n + 1):
    a, b, c = map(int, input().split())
    v[i], w[i], s[i] = a, b, c
for i in range(1, n + 1):
    for j in range(v1,v[i]-1,-1): #只要枚举体积比它大的,小的不用枚举
        for k in range(1, s[i] + 1):
            if k * v[i] > j:
                break
            dp[j] = max(dp[j], dp[j - k * v[i]] + k * w[i])
print(dp[v1])

多重背包问题 II 二进制优化

# https://www.acwing.com/problem/content/5/
n,v1=map(int,input().split())
dp=[0]*(2100+10)
v=[0]*(21000+10)
w=[0]*(21000+10)
t=0
for i in range(n):
    a,b,c=map(int,input().split())
    j=1
    while j<=c: ##将多个一样的物品组合在一起成为一个物品
        t+=1
        v[t]=j*a
        w[t]=j*b
        c -= j
        j*=2
    if c>0:
        t+=1
        v[t]=c*a
        w[t]=c*b
for i in range(1,t+1):
    for j in range(v1,v[i]-1,-1):
        dp[j]=max(dp[j],dp[j-v[i]]+w[i])
print(dp[v1])

背包问题求方案数

# https://www.acwing.com/problem/content/11/
n,v=map(int,input().split())
g=[1]*(v+10)
dp=[0]*(v+10)
for i in range(n):
    a,b=map(int,input().split())
    for j in range(v,a-1,-1):
        if dp[j]==(dp[j-a]+b):
            g[j]=(g[j]+g[j-a])%1000000007
        elif dp[j]<dp[j-a]+b:
            g[j]=g[j-a]%1000000007
        dp[j]=max(dp[j],dp[j-a]+b)
print(g[v])
#

背包问题求具体方案

#https://www.acwing.com/problem/content/12/
n, v = map(int, input().split())
v1, w1 = [0] * (n + 1), [0] * (n + 1)
dp = [[0 for i in range(v+2)] for j in range(n+2)]
for i in range(1, n + 1):
    a, b = map(int, input().split())
    v1[i], w1[i] = a, b
for i in range(n, -1, -1):   ##从后面开始算
    for j in range(v + 1):
        dp[i][j] = dp[i + 1][j]  #不选第i个物品
        if j >= v1[i]:  #选择第i个物品
            dp[i][j] = max(dp[i][j], dp[i + 1][j - v1[i]] + w1[i])
j = v
for i in range(1, n + 1): #依次向后遍历寻找最小的
    if j >= v1[i] and dp[i][j] == dp[i + 1][j - v1[i]] + w1[i]:
        print('%d '%i,end="")
        j -= v1[i]
print()

重建二叉树

# https://www.acwing.com/problem/content/23/
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution(object):
    def buildTree(self, preorder, inorder):
        if len(preorder)==0:
            return preorder
        if len(preorder)==1:
            return TreeNode(preorder[0])
        root=TreeNode(preorder[0])
        index=inorder.index(preorder[0])
        root.left=self.buildTree(preorder[1:index+1],inorder[:index])
        if index+1<len(inorder):
            root.right=self.buildTree(preorder[index+1:],inorder[index+1:])
        return root

自然数拆分

https://www.acwing.com/problem/content/281/
n = int(input())
dp = [0] * (n + 10)
dp[0]=1
for i in range(1,n+1):
    for j in range(i, n+1):
        dp[j] = (dp[j] + dp[j - i]) % 2147483648
print(dp[n]-1)

最长公共子序列

https://www.acwing.com/problem/content/3878/
n = int(input())
p1 = list(map(int, input().split()))
p2 = list(map(int, input().split()))
dp = [[0 for i in range(n + 1)] for j in range(n + 1)]
for i in range(1,n+1):
    for j in range(1,n+1):
        if p1[i-1] == p2[j-1]:
            dp[i][j]=dp[i-1][j-1]+1
        else:
            dp[i][j] = max(dp[i-1][j], dp[i][j-1])  ##如果是最长公共子串就是dp[i][j]=0
print(dp[n][n])

最长公共上升子序列模版

N = int(input())
lst_1 = [0] + list(map(int,input().split()))
lst_2 = [0] + list(map(int,input().split()))
#* dp[i][j] 第一个序列的前i个元素 与 第二个序列前j个字母 以b[j]结尾 的最长公共上升子序列长度
dp = [[0 for i in range(N+1)]for j in range(N+1)]
for i in range(1,N+1) : # 枚举第一个序列
    mx = 1
    for j in range(1,N+1) : # 枚举第二个序列
        dp[i][j] = dp[i-1][j] # 如果第一个序列的第i个数字 不等于 第二个序列的第j个数字
        if lst_1[i] == lst_2[j] : dp[i][j] = max(dp[i][j],mx) # 如果等于
        if lst_1[i] > lst_2[j] : mx = max(mx,dp[i-1][j]+1) # mx来储存当前a[i]>b[k]时 dp[i-1][k]+1的最大值
print(max(dp[N]))

最长上升子序列和

import copy
N = int(input())
lst = [0] + list(map(int,input().split()))
 
# 与最长上升子序列和相同的思路 不过是把+1换成+lst[i]
dp = copy.deepcopy(lst)
for i in range(N+1) :
    for j in range(i) :
        if lst[i] > lst[j] : dp[i] = max(dp[i],dp[j]+lst[i])
        
print(max(dp))
#最长回文子串
#https://www.acwing.com/problem/content/description/1526/
s=list(input())
res=0
for i in range(len(s)):
    l,r=i,i
    while l>=0 and r<len(s) and s[l]==s[r]:
        l-=1
        r+=1
    res=max(res,r-l-1)
    l,r=i,i+1
    while l>=0 and r<len(s) and s[l]==s[r]:
        l-=1
        r+=1
    res=max(res,r-l-1)
print(res)

N个字符/数字的全排列

from itertools import combinations
n,k=map(int,input().split())
s=[i for i in range(1,n+1)]
for comb in combinations(s,k):
   print("".join(map(str,comb)))

n个数字的不同排列

from itertools import permutations
n=int(input())
s=[i for i in input().split()]
for p in permutations(s):
  print("".join(map(str,p)))

n个字母的不同排列

str=list(input().split()) # 根据空格划分开
for p in permutations(str):
  print("".join(p))

N个字符选K个字符的组合

from itertools import combinations
n,k=map(int,input().split())
s=[i for i in range(1,n+1)]
for comb in combinations(s,k):
  print("".join(map(str,comb)))

X星购票

while True:
    try:
        n = int(input())
        n//=2
        dp = [[0 for i in range(n + 1)] for j in range(n + 1)]
        for i in range(1, n + 1):
            dp[i][0] = 1
        for i in range(1, n + 1):
            for j in range(1,i+1):
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
        print(dp[n][n])
    except:
        break

子串分值

#贡献度的计算 一个字符的贡献度便是包含一个此字符的子字符串个数,公式即是(左边的间隔+1)*(右边的间隔+1)

while True:
  try:
       k=list(input())
       cot=0
       for i in range(len(k)):
           nr,nl,loc,num=0,0,i-1,k[i]
           while loc>=0 and num!=k[loc]:
               loc-=1
               nl+=1
           loc=i+1
           while loc<len(k) and num!=k[loc]:
               loc+=1
               nr+=1
           cot+=(nl+1)*(len(k)-i)
       print(cot)
  except:
      break
import os
import sys
# 请在此输入您的代码
s=input()
a=[-1 for i in range(26)]
count=0
for i in range(len(s)):
  index=ord(s[i])-ord('a')
  count+=(len(s)-i)*(i-a[index])
  a[index]=i
print(count)    

砝码称重

while True:
  try:
      n=int(input())
      k=list(map(int,input().split()))
      cot=0
      p=set()
      p.add(0)
      k.sort()
      for i in k:
          for j in list(p):
              p.add(abs(j-i))
              p.add(j+i)
      print(len(p)-1)
  except:
      break

#能称出的 1010 种重量是:1、2、3、4、5、6、7、9、10、111、2、3、4、5、6、7、9、10、11​。

1 = 11=12 = 64 (2=64(天平一边放 66,另一边放 4)4)3 = 413=414 = 44=45 = 615=616 = 66=67 = 1 + 67=1+69 = 4 + 619=4+6110 = 4 + 610=4+611 = 1 + 4 + 611=1+4+6

数位dp

def init():
    global f ##i位有j个1的情况
    f=[[0 for i in range(100)] for j in range(100)]
    for i in range(100):
        for j in range(100):
            if j==0:
                f[i][j]=1
            else:  ##可以选择
                f[i][j]=f[i-1][j]+f[i-1][j-1]
    return f
def dp(n,k):
    list=[]
    num=n
    while num>0:
        list.append(num%2)
        num//=2
    last=k
    res=0
    for i in range(len(list)-1,-1,-1):
        if i==0 and last==1: ##最后一位为1的情况
          res+=1
        if list[i]==1:
            res+=f[i][last]
            last-=1
    return res
while True:
 try:
      f=init()
      n,k=map(int,input().split())
      print(dp(n,k))
##      st=0 比较贪心和数位dp的区别
##      c=0
##      for i in range(1,n+1):
##          if list(bin(i)[1:]).count("1")==k:
##              c+=1
##      print(c)
 except:
      break

数形dp

while True:
## try:
     dp=[0]
     for i in range(1,2022):
         dp.append(float("inf"))
         for j in range(i):
             dp[i]=min(dp[i],1+2*dp[j]+3*dp[i-j-1]+j*j*(i-j-1))
     print(dp[2021])
     break
## except:
##      break

递增三元组

#https://www.lanqiao.cn/problems/172/learning/?page=1&first_category_id=1&sort=students_count&name=%E4%B8%89%E5%85%83%E7%BB%84

import bisect
while True:
 try:
     n=int(input())
     A=list(map(int,input().split()))
     B=list(map(int,input().split()))
     C=list(map(int,input().split()))
     A.sort()
     B.sort()
     C.sort()
     s=0
     ##前提一定要有序
     for i in range(n):
         k=bisect.bisect_left(A,B[i])##大于等于B【i】的第一个下标
         c=n-bisect.bisect_right(C,B[i])##在C中寻找大于B【i】的第一个下标
         s+=k*c
     print(s)
 except:
      break

包子凑数

import math
while True:
 try:  ##对于a1*x+a2*x+a3*x+...=c如果a1,a2,an互质则有限个解,否则无限个解
     p=[0 for i in range(111111)]#最大不能凑出的数字为a1*a2-a1-a2
     n=int(input())
     f=[]
     s=0
     for i in range(n):
         f.append(int(input()))
     g=0
     for i in range(n):
         if i==0:
             g=f[i]
         else:
             g=math.gcd(g,f[i])

     if g!=1:
         print("INF")
     else:
         
         for i in range(n):
             p[f[i]]=1
             for j in range(10010):##如果p[j]存在,则p[j+f[i]]存在
                 if  p[j]==1:
                     p[j+f[i]]=1
         for i in range(1,10001):
             if p[i]==0:
                 s+=1
         print(s)
 except:
      break

背包与魔法

#https://www.lanqiao.cn/problems/2223/learning/?contest_id=89
while True:
 try:
     n,m,k=map(int,input().split())
     dp=[[0 for i in range(2)] for j in range(m+1)]## dp[i][0]为没有突变的,dp[i][1]为突变的
     for i in range(n):
         w,v=map(int,input().split())
         for j in range(m,w-1,-1):
           dp[j][1]=max(dp[j][1],dp[j-w][1]+v)
           if w+k<=j:
               dp[j][1]=max(dp[j][1],dp[j-w-k][0]+2*v)##满足条件就可以突变
           dp[j][0]=max(dp[j][0],dp[j-w][0]+v)
     print(max(dp[m][0],dp[m][1]))
 except:
      break

本质上升序列

#https://www.lanqiao.cn/problems/1021/learning/?contest_id=89
while True:
 try:
     k="tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhfiadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqijgihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmadvrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl"
     dp=[0 for i in range(len(k)+5)]
     for i in range(len(k)):
         dp[i]=1
         for j in range(i):
            if k[i]>k[j]:
                dp[i]+=dp[j]
            elif k[i]==k[j]:
                dp[i]-=dp[j]
     print(sum(dp))
     break
 except:
      break

回路计数

#https://www.lanqiao.cn/problems/1462/learning/?contest_id=89
import math
while True:
## try:
        g=[[0]*22 for i in range(22)]
        for i in range(1,22):
           for j in range(1,22):
               if math.gcd(i,j)==1:
                   g[i-1][j-1]=g[j-1][i-1]=1
        n=1<<21
        dp=[[0]*21 for i in range(n)]
        dp[1][0]=1
        i=1
        while i<n:
            for j in range(21):
                if i>>j&1==0:
                    continue
                if dp[i][j]==0:
                    continue
                for k in range(21):
                    if i>>k&1==0 and g[j][k]!=0:
                        dp[i+(1<<k)][k]+=dp[i][j]
            i+=1
        res=0
        for i in range(21):
            res+=dp[n-1][i]
        print(res)
        break
## except:
##      break

数组切分

#https://www.lanqiao.cn/problems/2148/learning/?contest_id=89
import math
while True:
     try:
         n=int(input())
         k=[0]+list(map(int,input().split()))
         f=[0 for i in range(n+1)]
         f[0]=1
         for i in range(1,n+1):
             maxn,minn=0,float("inf")
             for j in range(i,0,-1):#最后一个片段要一样
                 maxn=max(k[j],maxn)
                 minn=min(k[j],minn)
                 if i-j==maxn-minn:
                     f[i]=(f[i]+f[j-1])%1000000007 
         print(f[n])
     except:
          break

密码脱落 n*n

#https://www.lanqiao.cn/problems/124/learning/?contest_id=89
import math
import copy
while True:
     try:
         k=list(input())
         res=0
         k1=copy.deepcopy(k)
         k1.reverse()
         dp=[[0 for i in range(len(k)+1)] for j in range(len(k)+1)]
         for i in range(1,len(k)+1):
             for j in range(1,len(k)+1):
                 if k[i-1]==k1[j-1]:
                     dp[i][j]=dp[i-1][j-1]+1
                 else:
                     dp[i][j]=max(dp[i-1][j],dp[i][j-1])
         print(dp[len(k)][len(k)])
         print(len(k)-dp[len(k)][len(k)])
     except:
          break

最长回文子串

k=list(input())
res=1
for i in range(len(k)):
   L,R=i-1,i+1
   while L>=0 and R<len(k) and k[L]==k[R] :
             res=max(res,R-L+1)
             L-=1
             R+=1
   L,R=i,i+1
   while L>=0 and R<len(k) and k[L]==k[R]:
               res=max(res,R-L+1)
               L-=1
               R+=1
print(len(k)-res)

序列计数

#https://www.lanqiao.cn/problems/150/learning/?contest_id=89
def dsf(pre,cur):
    if cur<=0:
        return 0
    if dp[pre][cur]!=0:
       return dp[pre][cur]    
    dp[pre][cur]=(1+dsf(pre,cur-1)+dsf(cur,abs(pre-cur)-1))%10000
    return dp[pre][cur]
n=int(input())
dp=[[0 for i in range(1000)] for i in range(1000)]
print(dsf(n,n))

小明的衣服,哈夫曼

#https://www.lanqiao.cn/problems/1228/learning/?contest_id=88
from queue import PriorityQueue
n=int(input())
k=list(map(int,input().split()))
queue=PriorityQueue()
for x in k:
    queue.put(x)
s=0
while queue.qsize()>1:
     ind=queue.get()+queue.get()
     s+=ind
     queue.put(ind)
print(s)

123

#https://www.lanqiao.cn/problems/1591/learning/?contest_id=88
import math
def pre(x):
    f=int(math.sqrt(2*x+0.25)-0.5)//求是第几个
    ind=x-(f+1)*f//2 //减去前面的
    return p[f]+(ind+1)*ind//2 //前缀和加上后面的几个
q=[0]
p=[0]
for i in range(1,2000000):
    q.append(q[i-1]+i)
    p.append(p[i-1]+q[i])
n=int(input())
for i in range(n):
    l,r=map(int,input().split())
    print(pre(r)-pre(l-1))

四重循环的统计子矩阵

n,m,k=map(int,input().split())
a=[[0 for i in range(m+1)] for j in range(n+1)]
for i in range(1,n+1):
    b=list(map(int,input().split()))
    for j in range(1,m+1):
        a[i][j]=b[j-1]
for i in range(1,n+1):
    for j in range(1,m+1):
        a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+a[i][j]
res=0
for i in range(1,n+1):
    for ii in range(i,n+1):
        for j in range(1,m+1):
            for jj in range(j,m+1):
                if a[ii][jj]-a[ii][j-1]-a[i-1][jj]+a[i-1][j-1]<=k:
                    res+=1
print(res)

三重循环的统计子矩阵

n,m,k=map(int,input().split())
a=[[0 for i in range(m+1)] for j in range(n+1)]
for i in range(1,n+1):
    b=list(map(int,input().split()))
    for j in range(1,m+1):
        a[i][j]=b[j-1]
for i in range(1,n+1):
    for j in range(1,m+1):
        a[i][j]+=a[i-1][j]
res=0
for i in range(1,n+1):
    for j in range(i,n+1):
        L=1
        s=0
        for R in range(1,m+1):
           s+=a[j][R]-a[i-1][R]
           while s>k:
               s-=a[j][L]-a[i-1][L]
               L+=1
           res+=R-L+1
print(res)

递增序列

k=[]
for i in range(30):
    k.append(list(input()))
res=0
for i in range(30):
    for j in range(50):
        for ii in range(30):
            for jj in range(50):##5个方向寻找
                if (k[i][j]<k[ii][jj] and ii==i and j<jj) or (k[i][j]<k[ii][jj] and j==jj and ii>i)or ( abs(ii-i)==abs(jj-j) and k[i][j]<k[ii][jj] and not (i>=ii and j>=jj)):
                    res+=1

print(res)

含 2 天数

import datetime
time=datetime.date(1900,1,1)
s=0
end=datetime.date(9999,12,31)
while time<end:
    time+=datetime.timedelta(1)
    if str(time).count("2")>0:
        s+=1
print(s)

左孩子右兄弟

#https://www.lanqiao.cn/problems/1451/learning/?page=1&first_category_id=1&sort=students_count&name=%E5%B7%A6%E5%AD%A9%E5%AD%90%E5%8F%B3%E5%85%84%E5%BC%9F
import sys
sys.setrecursionlimit(100000) ##设置最大递归深度
def dsf(i):
    if dp[i] is None:
        return 0
    maxn=0
    for j in dp[i]:
        maxn=max(maxn,dsf(j))
    return  len(dp[i])+maxn
n=int(input())
dp=[[] for i in range(n+10)]
for i in range(2,n+1):
    p=int(input())
    dp[p].append(i)
print(dsf(1))

异或数列

##https://www.lanqiao.cn/problems/1450/learning/?page=1&first_category_id=1&sort=students_count&name=%E5%BC%82%E6%88%96%E6%95%B0%E5%88%97
t=int(input())
k=[]
for i in range(t):
    k=list(map(int,input().split()))
    a=[]
    sum1=0
    ma=0
    for x in k[1:]:
        a.append(x)
        sum1^=x
        ma=max(ma,x)
    if sum1==0: ##为0则为平局
        print(0)
        continue
    x=1
    while x<ma:#找到最高位
        x<<=1
    while x>0: #依次从最高位找
        one=0
        zero=0
        for re in a:
            if re&x!=0:
                one+=1
            else:
                zero+=1
        if one%2==1:  #1的个数为奇数才能分辨
            if zero%2==1 and one>1: #因为alice占有先权找最优,但是当0的个数为偶数时,后方会赢
                print(-1)
            else:
                print(1)
            break
        x>>=1

长草

##https://www.lanqiao.cn/problems/149/learning/?page=1&first_category_id=1&sort=students_count&name=%E9%95%BF%E8%8D%89
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

que=[]
qstart,qend=0,0
if __name__=='__main__':
    n,m=map(int,input().split())
    dp=[[0 for i in range(m)] for j in range(n)]
    for i in range(n):
        st=input()
        for j in range(m):
            dp[i][j]=st[j]
            if dp[i][j]=='g':
                que.append([i,j])
                qend+=1
    k=int(input())
    for i in range(k):
        length=qend-qstart
        for j in range(length):
            nowx=que[qstart+j][0]
            nowy=que[qstart+j][1]
            for p in range(4):
                if 0<=nowx+dx[p]<n and 0<=nowy+dy[p]<m and dp[nowx+dx[p]][nowy+dy[p]]==".":
                    que.append([nowx+dx[p],nowy+dy[p]])
                    qend+=1
                    dp[nowx+dx[p]][nowy+dy[p]]='g'
        qstart=qstart+length
    for i in range(n):
        st=""
        for j in range(m):
            st+=dp[i][j]
        print(st)

蜂巢

##https://www.lanqiao.cn/problems/2134/learning/?page=1&first_category_id=1&sort=students_count&second_category_id=3&name=%E8%9C%82%E5%B7%A2
x=[0,-1,-1,0,1,1]
y=[-1,0,1,1,0,-1]
def change(d,p,q):
    x1,y1=0,0
    x1+=x[d]*p
    y1+=y[d]*p
    x1+=x[(d+2)%6]*q
    y1+=y[(d+2)%6]*q
    return x1,y1
d1,p1,q1,d2,p2,q2=map(int,input().split())
a1,b1=change(d1,p1,q1)
a2,b2=change(d2,p2,q2)
f,s=a1-a2,b1-b2
if f*s>=0:
    print(abs(f)+abs(s))
else:
    print(max(abs(f),abs(s)))

全排列的价值

##https://www.lanqiao.cn/problems/2137/learning/?page=1&first_category_id=1&sort=students_count&second_category_id=3&name=%E5%85%A8%E6%8E%92%E5%88%97%E7%9A%84%E4%BB%B7%E5%80%BC
n=int(input())
res=((n-1)*n//2)% 998244353
for i in range(3,n+1):
    res=(res*i)% 998244353
print(res)

技能升级

##https://www.lanqiao.cn/problems/2129/learning/?page=1&first_category_id=1&sort=students_count&second_category_id=3&name=%E6%8A%80%E8%83%BD%E5%8D%87%E7%BA%A7
import math
n,m=map(int,input().split())
k=[]
for i in range(n):
    k.append(list(map(int,input().split())))
def check(x): #确定第m个大的数x
    s=0
    for i in range(n):
        if k[i][0]<=x:
            continue
        else:
            z=(k[i][0]-x)//k[i][1]
            s+=z+1
    return s>=m
L,x,R=0,0,1000000
while L<=R:
    mid=(L+R)//2
    if check(mid):
        L=mid+1
        x=mid
    else:
        R=mid-1
sum1=0
ans=0
for i in range(n): 
    if k[i][0]<=x:
        continue
    else:
        z=(k[i][0]-x)//k[i][1]
        if k[i][0]-k[i][1]*z>x:
            z+=1
        sum1+=((k[i][0]+k[i][0]-(z-1)*k[i][1])*z//2)
        ans+=z
sum1+=(m-ans)*x
print(sum1)

迪杰斯特拉模板

 while True:
     n, m = map(int, input().split())
     p = [[] for i in range(n + 1)]
     time = [[] for i in range(n + 1)]
     for i in range(m):
         u, v, w, t = map(int, input().split())
         p[u].append([v, w])
         p[v].append([u, w])
         time[u].append([v, t])
         time[v].append([u, t])
     dis = [float("inf") for i in range(n + 1)]
     tims = [float("inf") for i in range(n + 1)]
     dis[1] = 0
     tims[1] = 0
     lin = [1]
     while len(lin) > 0:
         current_point = lin[0]
         for v,j in enumerate(p[current_point]):
             if dis[j[0]] >= dis[current_point] + j[1]:
                 for i in time[current_point]:
                     if i[0]==j[0]:
                         if tims[j[0]] > tims[current_point] + time[j[0]][v][1]:
                             dis[j[0]] = dis[current_point] + j[1]
                             tims[j[0]] = tims[current_point] + time[j[0]][v][1]
                             if j[0] not in lin:
                                 lin.append(j[0])
                         break
         lin.remove(current_point)
     print(dis[n], tims[n])

最短路径模板

 while True:
     try:
         c, m, n = map(int, input().split())
         p = [[] for i in range(n + 1)]
         for i in range(m):
             x, y, z = map(int, input().split())
             p[x].append([y, z])
         dis = [float("inf") for i in range(n + 1)]
         dis[1] = 0
         lin = [1]
         while len(lin) > 0:
             current_point = lin[0]
             for j in p[current_point]:
                 dis[j[0]] = min(dis[j[0]], dis[current_point] + j[1])
                 if j[0] not in lin:
                     lin.append(j[0])
             lin.remove(current_point)
         if dis[n] <= c:
             print("Yes")
         else:
             print("No")
     except:
         break

树状数组模板

 def lowbit(i):
     return -i&i

 def add(i,p):
     j=i
     while j<=n:
         c[j]+=p
         j+=lowbit(j)
 def sum(i):
     q=0
     j=i
     while j>0:
         q+=c[j]
         j-=lowbit(j)
     return q
 def quyu(w,y):
     return sum(y)-sum(w-1)
 n,m=map(int,input().split())
 c=[0 for i in range(n+1)]
 s=list(map(int,input().split()))
 for i,x in enumerate(s):
     add(i+1,x)
 for i in range(m):
     a,b,c1=map(int,input().split())
     if a==1:
         add(b,c1)
     else:
         print(quyu(b,c1))

差分数组模板

 def init():
     c[0] = s[0]
     for i in range(1, n):
         c[i] = s[i] - s[i - 1]
 def result():
     s[0]=c[0]
     for i in range(1,n):
         s[i] = s[i-1] + c[i]
 n, q = map(int, input().split())
 s = list(map(int, input().split()))
 c = [0 for i in range(n+1)]
 init()
 for i in range(q):
     l, r, x = map(int, input().split())
     c[l-1] += x
     if r<n:
        c[r] -= x
 result()
 for x in s:
     if x<0:
         x=0
     print('%d ' % (x), end="")
 print()

dfs模板

 from collections import deque
 x=[0,0,-1,1]
 y=[1,-1,0,0]
 def bfs():
     queue=deque()
     queue.append([x1-1,y1-1,0])
     flag[x1-1][y1-1] = 1
     while queue:
         index=queue.popleft()
         x3,y3,t=index[0],index[1],index[2]
         if x3==x2-1 and y3==y2-1:
             print(t)
             return
         for i in range(4):
             x31=x3+x[i]
             y31=y3+y[i]
             if 0<=x31<n and 0<=y31<m and s[x31][y31]==1 and flag[x31][y31]==0:
                 queue.append([x31,y31,t+1])
                 flag[x31][y31]=1
     print(-1)
 n,m=map(int,input().split())
 s=[[0 for i in range(m)] for j in range(n)]
 flag=[[0 for i in range(m)] for j in range(n)]
 for i in range(n):
     k=list(map(int,input().split()))
     for j in range(m):
         s[i][j]=k[j]
 x1,y1,x2,y2=map(int,input().split())
 bfs()

背包模板

 n,v1=map(int,input().split())
 bag=[[0 for i in range(v1+1)] for j in range(n+1)]
 w=[0]
 v=[0]
 for i in range(n):
     a,b=map(int,input().split())
     w.append(a)
     v.append(b)
 for i in range(1,n+1):
     for j in range(1,v1+1):
         if w[i]<=j:
             bag[i][j]=max(bag[i-1][j],bag[i][j-w[i]]+v[i])
         else:
             bag[i][j]=bag[i-1][j]
 print(bag[n][v1])

最长递增字符串模板

 n = int(input())
 s = list(map(int, input().split()))
 b = [1 for i in range(n)]
 for j in range(n):
     maxlen=0
     for i in range(j - 1, -1, -1):
         if s[j] > s[i] and b[i] > maxlen:
             maxlen = b[i]
     b[j] = maxlen + 1
 print(max(b))

bisect二分查找解决

 import bisect
 n=int(input())
 s=list(map(int,input().split()))
 b=[]
 b.append(s[0])
 for i in range(1,n):
     index=bisect.bisect_left(b,s[i])  ##找到比s[i]
     if index>=len(b):
         b.append(s[index])
     else:
         b[index]=s[i]
 print(len(b))

二分差分模板

n,m=map(int,input().split())
 sum=0
 for i in range(m):
     l,r,s,e=map(int,input().split())##等差数列求和
     sum+=(s+e)*(r-l+1)//2
 print(sum)

并查集

 def init():
     for i in range(n):
         k.append(i + 1)

 def find(x):
     if x !=k[x]:
         k[x]=find(k[x])##路径压缩
     return k[x]
 n, m = map(int, input().split())
 k = [0]
 init()
 for i in range(m):
     op, x, y = map(int, input().split())
     x1 = find(x)
     y1 = find(y)
     if op == 1:
         if x1 != y1:
             k[x1]=k[y1] ##两个祖宗相连
     else:
         if x1 == y1:
             print('YES')
         else:
             print('NO')

敌人和朋友的并查集

 def init():
     for i in range(n):
         k.append(i + 1)

 def find(x):
     if x !=k[x]:
         k[x]=find(k[x])##路径压缩
     return k[x]
 n, m = map(int, input().split())
 k = [0]
 init()
 flag=0
 for i in range(m):
     x, y = map(int, input().split())
     x1 = find(x)
     y1 = find(y)
     x2 = find(k[x])
     y2 = find(k[y])
     if flag:
         continue
     if x1==y1 or x2==y2:
         flag=x
     else:
         k[x1]=k[y2]
         k[y1]=k[x2]
 print(flag)

最长公共字符串模板

 n,m=map(int,input().split())
 a=list(map(int,input().split()))
 b=list(map(int,input().split()))
 flag=[[0 for i in range(m+1)] for j in range(n+1)]
 for i in range(n):
     for j in range(m):
         if a[i]==b[j]:
             flag[i+1][j+1]=flag[i][j]+1
         else:
             flag[i+1][j+1]=max(flag[i][j+1],flag[i+1][j])
 print(flag[n][m])

floyd模板

 n,m,q=map(int,input().split())
 flag=[[9999999999 for i in range(n+1)] for j in range(n+1)]
 for i in range(m):
     u,v,w=map(int,input().split())
     flag[u][v]=w
 for i in range(1,n+1):
     for j in range(1,n+1):
         if i==j:
             flag[i][j]=0
 for i in range(1,n+1):
     for k in range(1,n+1):
         # if flag[i][k]!=9999999999:
             for j in range(1,n+1):
                 if flag[k][j]+flag[j][i]<flag[k][i]:
                     flag[k][i]=flag[k][j]+flag[j][i]
 for i in range(q):
     st,ed=map(int,input().split())
     if flag[st][ed]==9999999999:
         print(-1)
     else:
         print(flag[st][ed])

单调栈模板

 n = int(input())
 k = list(map(int, input().split()))
 p = []
 ans = [-1 for i in range(n)]
 for i in range(n):
     while len(p) > 0 and k[p[-1]]<=k[i]:##栈不为空,栈点数小于原数的去掉
         p.pop()
     if len(p) != 0:
         ans[i] =p[-1]+1
     else:
         ans[i] = -1
     p.append(i)
 for x in ans:
     print('%d '%x,end="")
 print()
 p=[]
 ans = [-1 for i in range(n)]
 for i in range(n-1,-1,-1):
     while len(p) > 0 and k[p[-1]]<=k[i]:
         p.pop()
     if len(p) != 0:
         ans[i] =p[-1]+1
     else:
         ans[i] = -1
     p.append(i)
 for x in ans:
     print('%d '%x,end="")
 print()

哈夫曼树模板

 from queue import PriorityQueue
 n=int(input())
 k=list(map(int,input().split()))
 queue=PriorityQueue()
 for x in k:
     queue.put(x)
 cout=0
 while queue.qsize()>1:
     t=queue.get()+queue.get()
     cout+=t
     queue.put(t)
 print(cout)

尺取法模板

 n,c=map(int,input().split())
 k=list(map(int,input().split()))
 r=0
 l=0
 k.sort()
 ans=0
 for i in range(n):  ##r和l之间的数一样,如果r小于就往前移动,如果l小于也往前面移动
     while r<n and k[r]-k[i]<=c:
         r+=1
     while l<n and k[l]-k[i]<c:
         l+=1
     r-=1  #防止右边出界
     if r>0 and k[r]-k[i]==c and k[l]-k[i]==c :
         ans+=r-l+1
 print(ans)

快速幂模板

 def algorithm(base,power):
     result=1
     while power>0:
         if power%2==0:
             base=(base*base)%p
             power//=2
         else:
             result=(result*base)%p
             power-=1
             power//=2
             base=(base*base)%p
     return result
 t=int(input())
 for i in range(t):
     n,m,p=map(int,input().split())
     print(algorithm(n,m))

st表模板

 n,q=map(int,input().split())
 flag=[[0 for i in range(n+1)] for j in range(n+1)]
 k=list(map(int,input().split()))
 for i in range(n):
     for j in range(i,n):
         if i==j:
             flag[i+1][j+1]=k[i]
         else:
             flag[i+1][j+1]=max(flag[i+1][j],k[j])
 for i in range(q):
     l,r=map(int,input().split())
     print(flag[l][r])

heapq库的迪杰斯特拉算法

#利用heapq建立最小堆
 import heapq
 n, m = map(int, input().split())
 k = [dict() for i in range(n)]
 for i in range(m):
     u, v, w = map(int, input().split())
     if v - 1 not in k[u - 1].keys():
         k[u - 1][v - 1] = w
     else:
         k[u - 1][v - 1] = min(k[u - 1][v - 1], w)
 dis = [float("inf") for i in range(n)]
 line = []
 dis[0] = 0
 vis = [0 for i in range(n)]
 heapq.heappush(line, [0, 0])
 while len(line) > 0:
     currentpoint = heapq.heappop(line)[1]
     if vis[currentpoint] == 1:
         continue
     else:
         for k1, v in k[currentpoint].items():
             if vis[k1] == 1: continue
             dis[k1] = min(dis[currentpoint] + v, dis[k1])
             heapq.heappush(line, [dis[k1],k1])
         vis[currentpoint] = 1
 for x in dis:
     if x == float("inf"):
         x = -1
     print('%d ' % x, end="")

美丽的区间尺取法模板

 n, s = map(int, input().split())
 a = list(map(int, input().split()))
 sum1 = 0
 cout = float("inf")

 if sum(a) < s:
     print(0)
 if sum(a)==s:
     print(n)
 elif sum(a)>s:
     j, k = 0, 0
     while j < n:  ##大于时后面的往前面移动
         if sum1 >= s:
             cout = min(j - k, cout)
             sum1 -= a[k]
             k += 1
         else:  ##小于时,往前面移动
             sum1 += a[j]
             j += 1
         # if j>=n or k>=n:
         #     break
     print(cout)

LCIS最长公共上升子序列模板

n,m=map(int,input().split())
 a=list(map(int,input().split()))
 b=list(map(int,input().split()))
 dp=[[0 for i in range(m)] for j in range(n)]
 ans=0
 for i in range(n):
     mx=0
     for j in range(m):
         if a[i]!=b[j]:
             dp[i][j]=dp[i-1][j]
         else:
            dp[i][j]=mx+1
         if b[j]<a[i]:
             mx=max(dp[i-1][j],mx)

 for i in range(n):
     ans=max(ans,max(dp[i]))
 print(ans)

数字三角形

while True:
    try:
         n=int(input())
         k=[]
         for i in range(n):
             k.append(list(map(int,input().split()))+[0,0])
         dp=[[0 for i in range(j+2)] for j in range(n+1)]
         dp[0][0]=k[0][0]
         for i in range(1,n):
             for j in range(i+1):
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+k[i][j]
         if n%2:
              print(dp[n-1][(n//2)])
         else:
             print(max(dp[n-1][(n//2)],dp[n-1][((n-1)//2)]))
    except:
        break
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不会敲代码的破茧

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

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

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

打赏作者

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

抵扣说明:

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

余额充值