前言

整体评价
属于补题,大致看了下,题都很典。
欢迎关注
珂朵莉 牛客周赛专栏
珂朵莉 牛客小白月赛专栏
A. 小红的 01 背包
思路: 数学题
v, x, y = list(map(int, input().split()))
print (v // x * y)
B. 小红的 dfs
思路: 枚举
其实横竖都有dfs字符,只有3种情况
- 第一行,第一列为dfs
- 第二行,第二列为dfs
- 第三行,第三列为dfs
枚举取最小代价即可
grids = []
for i in range(3):
    grids.append(input())
    
# 枚举
def cost(y, x, ch) -> int:
    if grids[y][x] == ch:
        return 0
    return 1
r1 = cost(0, 0, 'd') + cost(0, 1, 'f') + cost(0, 2, 's') \
    + cost(1, 0, 'f') + cost(2, 0, 's')
r2 = cost(1, 0, 'd') + cost(1, 1, 'f') + cost(1, 2, 's') \
    + cost(0, 1, 'd') + cost(2, 1, 's')
r3 = cost(2, 0, 'd') + cost(2, 1, 'f') + cost(2, 2, 's') \
    + cost(0, 2, 'd') + cost(1, 2, 'f')
print (min(r1, r2, r3))
C. 小红的排列生成
思路: 贪心
猜结论,感觉就是排序后
累加 abs(i - arr[i])
n = int(input())
arr = list(map(int, input().split()))
arr.sort()
res = 0
for i in range(n):
    res += abs(i + 1 - arr[i])
print (res)
D. 小红的二进制树
思路: 树形DP
自底向上的DFS即可
n = int(input())
s = input()
g = [[] for _ in range(n + 1)]
for i in range(n - 1):
    u, v = list(map(int, input().split()))
    g[u].append(v)
    g[v].append(u)
    
from types import GeneratorType
def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to
    return wrappedfunc
    
# python dfs会栈溢出
dp = [0] * (n + 1)
@bootstrap
def dfs(u: int, fa: int):
    for v in g[u]:
        if v == fa:
            continue
        yield dfs(v, u)
        dp[u] += dp[v]
    if s[u - 1] == '1':
        dp[u] += 1
    yield
dfs(1, -1)
for i in range(1, n + 1):
    print (dp[i] - (1 if s[i - 1] == '1' else 0))
E. 小红的回文数
思路: 前缀和 + 异或map技巧
就是0~9这10个构建一个字符集
由于奇偶特性可以借助异或来表达
这样就变成1024种状态
时间复杂度为
O ( 10 ∗ n ) O(10 * n) O(10∗n)
x = input()
from collections import Counter
cnt = Counter()
cnt[0] = 1
res = 0
s = 0
for c in x:
    p = ord(c) - ord('0')
    s ^= (1 << p)
    res += cnt[s]
    for i in range(10):
        res += cnt[s ^ (1 << i)]
    cnt[s] += 1
    
print (res)
F. 小红的矩阵修改
思路: 状压 + 3进制
很典的一道状压入门题
时间复杂度:
O ( 3 2 n ∗ m ) O(3^{2n} * m) O(32n∗m)
n, m = list(map(int, input().split()))
def mapping(c) -> int: 
    if c == 'r': 
        return 0
    elif c == 'e':
        return 1
    return 2
grids = []
for i in range(n):
    s = input()
    grids.append([mapping(c) for c in s])
# 状压DP
# 3进制
from math import pow, inf
y = int(pow(3, n))
dp = [0] * y
def compute(idx, state) -> int:
    if not isValid(state):
        return inf
    
    cost = 0
    for i in range(n):
        d = state % 3
        state = state // 3
        if grids[i][idx] != d:
            cost += 1
    return cost
def isValid(state) -> bool:
    r = []
    for i in range(n):
        r.append(state % 3)
        state = state // 3
    for i in range(len(r) - 1):
        if r[i] == r[i+1]:
            return False
    return True
def twoValid(s1: int, s2: int) -> bool:
    r1, r2 = [], []
    for i in range(n):
        r1.append(s1 % 3)
        s1 = s1 // 3
        r2.append(s2 % 3)
        s2 = s2 // 3
    for i in range(len(r1) - 1):
        if r1[i] == r1[i+1] or r2[i] == r2[i+1]:
            return False
    for i in range(len(r1)):
        if r1[i] == r2[i]:
            return False
    return True
            
for i in range(y):
    dp[i] = compute(0, i)
    
for j in range(1, m):
    dp2 = [inf] * y
    for k in range(y):
        c = compute(j, k)
        for k2 in range(y):
            if twoValid(k, k2):
                dp2[k] = min(dp2[k], dp[k2] + c)
    dp = dp2
print(min(dp))    
写在最后




















![基础IO[一]](https://img-blog.csdnimg.cn/direct/0192bf8e152b45dda673209a440bbbbd.png)