蓝桥杯~算法训练 Sereja and Squares(python)

试题 算法训练 Sereja and Squares

提交此题
资源限制
时间限制:4.0s 内存限制:256.0MB
问题描述
  Sereja在平面上画了n个点,点i在坐标(i,0)。然后,Sereja给每个点标上了一个小写或大写英文字母。Sereja不喜欢字母"x",所以他不用它标记点。Sereja认为这些点是漂亮的,当且仅当:
  ·所有的点可以被分成若干对,使得每个点恰好属于一一对之中。
  ·在每对点中,横坐标较小的会被标上小写字母,较大的会被标上对应的大写字母。
  ·如果我们在每对点上画一个正方形,其中已知的一对点会作为正方形的相对的顶点,它们间的线段会成为正方形的对角线,那么在所有画出的正方形中不会有相交或触碰的情况。
  小Petya擦掉了一些小写字母和所有大写字母,现在Sereja想知道有多少种方法来还原每个点上的字母,使得还原后这些点是漂亮的。
输入格式
  第一行是一个整数n,表示点的个数。
  第二行是一个长度为n的字符串,包含小写字母和问号"?",是按照横坐标递增的顺序的每个点的描述。问号表示这个点的字母被Petya擦掉了。保证输入串不含字母"x"。
输出格式
  输出答案对4294967296取模的值。如果没有可行的方案,输出0。
样例输入
4
a???
样例输出
50
样例输入
4
abc?
样例输出
0
样例输入
6
abc???
样例输出
1
数据规模和约定
  20个测试点的n分别为:
  5,10,20,50,100,
  200,500,1000,2000,5000,
  10000,20000,30000,40000,50000,
  60000,70000,80000,90000,100000.

n=int(input())
s=list(input())
dp=[[0for i in range(n)] for j in range(2)]
m=0
n2=n//2
now=0
dp[0][0]=1
for i in range(n):
    if s[i]=='?':
        now^=1
        for j in range((i+1)//2+1):
            #print(now,j)
            dp[now][j]=dp[now^1][j]+dp[now^1][j-1]
        #print(dp[now])
    else:
        m+=1
if (n2<m or n%2!=0):
    print(0)
else :
    for i in range(n2-m):
        dp[now][n2]*=25
        dp[now][n2]=dp[now][n2]%4294967296
    print(dp[now][n2])
n=int(input())
s=list(input())
#dp=[[0]*n for i in range(n)]
f=[0]*n
f[0]=1
m=0
n2=n//2   #n>>1
#print (n2)
for i in range(n):
    if s[i]=='?':
        j=(i+1)//2  #(i+1)>>1
        while j>=1:#max(1,(i+1)-n2)
            f[j]+=f[j-1]
            j-=1
        print(f)
    else:
        m+=1
print(f)
if (n2<m or n%2!=0):
    print(0)
else:
    i=n2-m
    while i>0:
        f[n2]*=25
        f[n2]= f[n2]%4294967296
        i-=1
    print(f[n2])

思路

我们dp里面储存的是前i个字符串里面存在j个大的字母的情况有几种,最后再乘25就好了。

  • 一个细节是乘的时候我们乘的是不确定选啥字母的才乘也就是n2-m个
  • i+1的时候假如加上的是一个?,那么dp[i+1][j]=dp[i][j]+dp[i][j-1]即之前的j个大字母的情况(?是小字母)+之前j-1个大字母的情况(?是大字母)。

你可能感兴趣的:(算法,数据结构与算法课程,蓝桥杯)