当前位置:   article > 正文

【3.29百度笔试编程解析】CodeForces 149D 括号染色问题 dp+dfs好题_一个长度为 的合法括号序列,每对匹配括号可以不染色、染白色、染黑色,染白色和

一个长度为 的合法括号序列,每对匹配括号可以不染色、染白色、染黑色,染白色和

题目大意

给一个给定括号序列,给该括号上色,上色有三个要求

1、只有三种上色方案,不上色,上红色,上蓝色

2、每对括号必须只能给其中的一个上色

3、相邻的两个不能上同色,可以都不上色
在这里插入图片描述

题目分析

求0-len-1这一区间内有多少种上色方案,很明显的区间DP

dp[l][r][i][j]表示l-r区间两端颜色分别是i,j的方案数

0代表不上色,1代表上红色,2代表上蓝色

对于l-r区间,有3种情况

1、if(l+1==r) 说明就只有一对,那么

dp[l][r][0][1]=1;
dp[l][r][1][0]=1;
dp[l][r][0][2]=1;
dp[l][r][2][0]=1;
  • 1
  • 2
  • 3
  • 4

2、if(l与r是配对的)

递归(l+1,r-1)

状态转移

dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod; 

dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;

dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;

dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3、if(l与r不配对)

dp[l][r][i][j]=(dp[l][r][i][j]+(dp[l][p][i][k]*dp[p+1][r][q][j])%mod)%mod;
  • 1

上代码走起

import sys
s=input()
num=strlen=len(s)  
tmp=[0 for i in range(num)] #记录左括号的位置
match=[0 for i in range(num)] #记录右匹配的位置
dp=[[[[0 for i in range(3)]for i in range(3)]for i in range(num)]for i in range(num)]
# 由内向外建立多维dp 数组的形式
# dp=np.arange(3*3*num*num).reshape(num,num,3,3)
mod=1000000007  
def getmatch(len) : 
    p=0
    for i in range(len):
        if(s[i]=='(') :
            tmp[p]=i
            p=p+1
        else:
            match[i]=tmp[p-1]  
            match[tmp[p-1]]=i  
            p=p-1
def dfs(l, r):  
    if (l+1==r):  #边界条件
        dp[l][r][0][1]=1 
        dp[l][r][1][0]=1 
        dp[l][r][0][2]=1
        dp[l][r][2][0]=1
        return   
    if(match[l]==r):    #如果匹配的话方案数相加
        dfs(l+1,r-1) 
        for i in range(3):
            for j in range(3):
                if(j!=1):  
                    dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;  
                if(i!=1):
                    dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;  
                if(j!=2):
                    dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;  
                if(i!=2):
                    dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;  
        return 
    else:    #否则方案数相乘,乘法原理
        p=match[l]
        dfs(l,p)  
        dfs(p+1,r) 
        for i in range(3):
            for j in range(3):
                for k in range(3):
                    for q in range(3):
                        if not((k==1 and q==1) or (k==2 and q==2)):
                             dp[l][r][i][j]=(dp[l][r][i][j]+(dp[l][p][i][k]*dp[p+1][r][q][j])%mod)%mod
if __name__=='__main__':
    getmatch(strlen)
    dfs(0,strlen-1) 
    ans=0  
    for i in range(3):
        for j in range(3):
            ans=(ans+dp[0][strlen-1][i][j])%mod;     
    sys.stdout.write(str(ans))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

python创建多维数组的3种方式

#coding=utf-8
import numpy as np
#1
image =[[(col+1)*(row+1) for col in range(5)] for row in range(3)]
a = np.array(image)
print(a)
 
#2
new_image =np.zeros((3,5))
 
#3
b = np.arange(12).reshape(3,4)
print(b)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/72560
推荐阅读
相关标签
  

闽ICP备14008679号