题目描述:
Petya遇到了一个关于括号序列的问题: 给定一个字符串S,它代表着正确的括号序列,即(“(”)与 (“)”)是匹配的。例如:“(())()” 和 “()”是正确的,“)()”与“(()”则不是正确的。 在正确的括号序列中,一个左边的括号一定是匹配一个右边的括号(反之亦然)。例如,在下图中,第 3 个括号匹配第 6 个括号,第 4 个括号匹配第 5 个括号。
现在你需要对一个正确的括号序列做涂色操作,严格满足以下三个条件:
1、每个括号要么不涂色,要么涂红色,要么涂蓝色。
2、一对匹配的括号需要且只能将其中一个涂色。
3、相邻的括号不能涂上同一种颜色(但是可以都不涂颜色)。
求:给整个括号序列涂上颜色的方案数,答案可能比较大,对 1000000007 取模。
输入:
输入的第一行包含一个字符串 s,(2 <= |s| <= 700)代表一个正确的括号序列。
输出:
输出方案数。(对 10^9 + 7 取模)。
样例输入1:
(())
样例输出1:
12
样例输入2:
(()())
样例输出2:
40
样例输入3:
()
样例输出3:
4
思路:
思想:啊啊啊!是一道紫题。手:我觉得我又行了但是还是不行,只是在挖坑。这道题相对来说比较亲民一点,但是一道紫题~~谈何容易,你以为的就是你以为以为的吗?~~但是这道题来说,需要加上一些预先处理以及颜色限制,显然这道题就不是什么男女老幼都可以做的题。
说了一堆废话让我们切入主题。
由题可知,这道题有颜色限制括号的匹配所以说,有三种分类情况:
1.i 不染颜色。
2.i 染成红色。
3.i 染成蓝色。
易得 DP可以被定义成为dp[i][j][0]
或dp[i][j][1]
或dp[i][j][2]
。[i.j]
为区间。j 同理的方案数,递归长序列,dp 合并小序列。
最主要的是其他情况,而且据我所知,是最麻烦的一种情况,他是两个或以上的括号序列组成的,所以需要我们依次把,这些划分出来。
这道题主要使用的队列,栈以及记忆化搜索,还有我们才学的区间DP啊~
代码:
#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#include<cstring>
#include<stack>
#define mod 1000000007
using namespace std;
stack<long long> s;
long long dp[705][705][3][3],ap[705],n;
char a[705];
void dfs(long long f,long long g){
if(f+1==g){
dp[