# 13 组合问题
[n,k]=list(map(int,input().split()))
res=[]
def fact(n):
if n == 1:
return 1
m = n * fact(n - 1)
print(m)
return m
def totalSum(n,k):
return fact(n)/(fact(k)*fact(n-k))
def backtracking(stratIndex,path):
if len(path)==k:
return res.append(path[:])
for i in range(stratIndex,n-k+2+len(path)):
path.append(i)
backtracking(i+1,path)
path.pop()
backtracking(1,[])
print(res)
#14 异或总和
nums=list(map(int,input().split()))
def XOR(num):
cnt=0
for i in num:
cnt=cnt^i
return cnt
def allSubset(arr):
sub=[[]]
for i in range(len(arr)):
for j in range(len(sub)):
sub.append(sub[j]+[(arr[i])])
return sub
sub=allSubset(nums)
res=0
for i in sub:
res+=XOR(i)
print(res)
#15 分割字符串
def isParlindrome(s):
return all(s[i] == s[len(s) - 1 - i] for i in range(len(s) // 2))
def backtracking(s, path, start_index, res):
if start_index == len(s):
return res.append(path[:])
for i in range(start_index, len(s)):
if isParlindrome(s[start_index:i + 1]):
path.append(s[start_index:i + 1])
backtracking(s, path, i + 1, res)
path.pop()
s = input()
res=[]
backtracking(s, [], 0,res)
print('[', end='')
for i in range(len(res)):
print('[', end='')
for j in range(len(res[i])):
if j == len(res[i]) - 1:
print(res[i][j], end=']')
else:
print(res[i][j], end=', ')
if i != len(res) - 1:
print(', ', end='')
print(']')
#16 目标和
cnt = 0
def dfs(nums, i, target, tmpSum):
global cnt
if i >= len(nums):
if tmpSum == target:
cnt += 1
return
dfs(nums, i + 1, target, tmpSum + nums[i])
dfs(nums, i + 1, target, tmpSum - nums[i])
nums = list(map(int, input().split()))
target = int(input())
dfs(nums, 0, target, 0)
print(cnt)
#17 组合问题
[n, k] = list(map(int, input().split()))
def backtracking(path, start_index, res):
if len(path) == k:
return res.append(path[:])
for i in range(start_index, n):
path.append(i + 1)
backtracking(path, i + 1, res)
path.pop()
res=[]
backtracking([],0,res)
for i in res:
for j in i[:-1]:
print(j,end=' ')
print(i[-1],end='')
if i!=res[-1]:
print("")
#18 大礼包
from math import inf
p_s = list(map(int, input().split()))
price = p_s[:-1]
lenSpecial = p_s[-1]
special = []
for i in range(lenSpecial):
special.append(list(map(int, input().split())))
needs = list(map(int, input().split()))
def dotmul(a, b):
return sum([a[i] * b[i] for i in range(len(a))])
def dotsub(a, b):
return [a[i] - b[i] for i in range(len(a))]
def dotchk(a):
return any([c < 0 for c in a])
def dp(t):
if dotchk(t):
return inf
ans = dotmul(price, t)
for sp in special:
ans = min(ans, sp[n] + dp(tuple(dotsub(t, sp[:n]))))
return ans
n = len(needs)
res = dp(tuple(needs))
print(res)
#19 K个总和相等的子集
nums = list(map(int, input().split()))
k = int(input())
res = []
def dfs(i):
if i == len(nums):
return "true"
for j in range(k):
if j and cur[j] == cur[j - 1]:
continue
cur[j] += nums[i]
if cur[j] <= s and dfs(i + 1):
return "true"
cur[j] -= nums[i]
return "false"
s, mod = divmod(sum(nums), k)
if mod:
print("false")
else:
cur = [0] * k
nums.sort(reverse=True)
print(dfs(0))
#21 硬币问题
target = int(input())
coins = list(map(int, input().split()))
dp=[0]*(target+1)
dp[0]=1
for coin in coins:
for i in range(coin,target+1):
dp[i]+=dp[i-coin]
print(dp[-1])
#22 打家劫舍
def rob(nums):
if len(nums) == 0:
return 0
# 子问题:
# f(k) = 偷 [0..k) 房间中的最大金额
# f(0) = 0
# f(1) = nums[0]
# f(k) = max{ rob(k-1), nums[k-1] + rob(k-2) }
N = len(nums)
dp = [0] * (N+1)
dp[0] = 0
dp[1] = nums[0]
for k in range(2, N+1):
dp[k] = max(dp[k-1], nums[k-1] + dp[k-2])
return dp[N]
nums = list(map(int, input().split()))
print(rob(nums))
#23 戳气球
def maxCoins(nums):
#nums首尾添加1,方便处理边界情况
nums.insert(0,1)
nums.insert(len(nums),1)
store = [[0]*(len(nums)) for i in range(len(nums))]
def range_best(i,j):
m = 0
#k是(i,j)区间内最后一个被戳的气球
for k in range(i+1,j): #k取值在(i,j)开区间中
#以下都是开区间(i,k), (k,j)
left = store[i][k]
right = store[k][j]
a = left + nums[i]*nums[k]*nums[j] + right
if a > m:
m = a
store[i][j] = m
#对每一个区间长度进行循环
for n in range(2,len(nums)): #区间长度 #长度从3开始,n从2开始
#开区间长度会从3一直到len(nums)
#因为这里取的是range,所以最后一个数字是len(nums)-1
#对于每一个区间长度,循环区间开头的i
for i in range(0,len(nums)-n): #i+n = len(nums)-1
#计算这个区间的最多金币
range_best(i,i+n)
return store[0][len(nums)-1]
nums = list(map(int, input().split()))
print(maxCoins(nums))
#24 分发糖果
def candy(ratings):
left = [1 for _ in range(len(ratings))]
right = left[:]
for i in range(1, len(ratings)):
if ratings[i] > ratings[i - 1]: left[i] = left[i - 1] + 1
count = left[-1]
for i in range(len(ratings) - 2, -1, -1):
if ratings[i] > ratings[i + 1]: right[i] = right[i + 1] + 1
count += max(left[i], right[i])
return count
nums = list(map(int, input().split()))
print(candy(nums))
#25 水壶问题
def canMeasureWater( x, y, z) -> bool:
stack = [(0, 0)]
seen = set()
while stack:
remain_x, remain_y = stack.pop()
if remain_x == z or remain_y == z or remain_x + remain_y == z:
return "true"
if (remain_x, remain_y) in seen:
continue
seen.add((remain_x, remain_y))
# 把 X 壶灌满。
stack.append((x, remain_y))
# 把 Y 壶灌满。
stack.append((remain_x, y))
# 把 X 壶倒空。
stack.append((0, remain_y))
# 把 Y 壶倒空。
stack.append((remain_x, 0))
# 把 X 壶的水灌进 Y 壶,直至灌满或倒空。
stack.append((remain_x - min(remain_x, y - remain_y), remain_y + min(remain_x, y - remain_y)))
# 把 Y 壶的水灌进 X 壶,直至灌满或倒空。
stack.append((remain_x + min(remain_y, x - remain_x), remain_y - min(remain_y, x - remain_x)))
return "false"
[x,y,z] = list(map(int, input().split()))
print(canMeasureWater(x,y,z))
#26 摆动序列
def wiggleMaxLength(nums) -> int:
n = len(nums)
if n < 2:
return n
up = [1] + [0] * (n - 1)
down = [1] + [0] * (n - 1)
for i in range(1, n):
if nums[i] > nums[i - 1]:
up[i] = max(up[i - 1], down[i - 1] + 1)
down[i] = down[i - 1]
elif nums[i] < nums[i - 1]:
up[i] = up[i - 1]
down[i] = max(up[i - 1] + 1, down[i - 1])
else:
up[i] = up[i - 1]
down[i] = down[i - 1]
return max(up[n - 1], down[n - 1])
nums = list(map(int, input().split()))
print(wiggleMaxLength(nums))
# 27 最长不重复子串
def lengthOfLongestSubstring(s):
dic = {}
i, ans = -1, 0
for j in range(len(s)):
if s[j] in dic:
i = max(dic[s[j]], i)
ans = max(ans, j - i)
dic[s[j]] = j
return ans
s=input()
print(lengthOfLongestSubstring(s))