AtCoder abc129

C Typical Stairs
斐波那契的变种,有障碍时填0
D Lamp
对每个点维护四个方向可以延伸的最长值
E - Sum Equals Xor
数位dp
f ( p o s , x , c a p ) f(pos, x, cap) f(pos,x,cap)
表示在二进制表示下,当前搜索到pos位
因为当前位只有三种可能 (0,0) (1,0) (0,1)
x=1表示(1,0)或者(0,1),即和为1
x=0表示和为0
cap表示之前是否已经达到取值的上限,即如果cap=1,那么必须要考虑和不能超过给定s的值,如果cap=0,那么不需要考虑取值问题
推理见代码

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @author   : [email protected]
# @desc     :
# @file     : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    s = fp.readline().strip()
    n = len(s)

    mod = 10 ** 9 + 7
    mem = {}

    def get(pos, x, cap):  # 记忆化TLE
        if pos == n:
            return 1
        if (pos, x, cap) in mem:
            return mem[(pos, x, cap)]
        if cap == 0:
            ret = get(pos + 1, 0, 0) + 2 * get(pos + 1, 1, 0)
        else:
            if s[pos] == '0':
                ret = get(pos + 1, 0, 1)
            else:
                ret = get(pos + 1, 0, 0) + 2 * get(pos + 1, 1, 1)
        return ret % mod

    dp = [[[0] * 2 for i in range(2)] for j in range(n + 1)]
    for i in range(2):
        for j in range(2):
            dp[n][i][j] = 1
    for i in range(n - 1, -1, -1):
        for j in range(2):
            dp[i][j][0] = (dp[i + 1][0][0] + 2 * dp[i + 1][1][0]) % mod
            if s[i] == '0':
                dp[i][j][1] = dp[i + 1][0][1]
            else:
                dp[i][j][1] = (dp[i + 1][0][0] + 2 * dp[i + 1][1][1]) % mod

    ans = dp[0][0][1]
    print(ans % mod)


if __name__ == "__main__":
    main()

你可能感兴趣的:(Atcoder,python,算法,Atcoder)