Problem A. Big Buttons
题意
定义一种序列,只含有R和B。给出一个目标长度N,和P个非法前缀。问有多少个长度为N的这种序列,不以非法前缀开头。
范围
1≤P≤min(2^N,100)
Small 1≤N≤10
Large 1≤N≤50
分析
所有长度为N的序列个数为$2^N$,但是其中还有一些非法前缀开头的序列,应当删去。
易知,以一个长度为L的非法前缀开头的序列有$2^{N-L}$个。
但是,这P个非法前缀中可能有一些是其它一些的前缀,在这种情况下,不能直接用上面的式子做减法。
举例而言,如果N为4,非法前缀有两个——
RB
RBR
那么,所有以RBR
开头的序列都是以RB
开头的序列,即我们在删除以RB
开头的序列时就删除了以RBR
开头的序列。
为了避免这样的前缀造成重复删除某些序列的情况,我们只考虑那些在非法前缀里“比较短”的前缀序列。
具体而言,就是没有任何其它非法前缀是该前缀序列的前缀。
对于这些“比较短”的非法前缀,设其组成集合$S$,那么答案就是——
$$ 2^N - \sum_{s \in S}{2^{N-|s|}} $$
其中$|s|$表示一个非法前缀$s$的长度。
代码
if __name__ == '__main__':
testCases = int(input())
for case in range(testCases):
n, m = input().strip().split()
n = int(n)
m = int(m)
ans = 2**n
ban = sorted([input().strip() for i in range(m)])
for index, prefix in enumerate(ban):
flag = True
for i in range(index):
if prefix.startswith(ban[i]):
flag = False
if flag:
ans -= 2**(n - len(prefix))
print('Case #{}: {}'.format(case + 1, ans))