CodeForces 149D 括号染色问题 dp+dfs好题
2013-12-12 20:36
309 查看
题意:给出一串已经匹配好的括号,现在要给它们上色,每个括号可以选择蓝色,红色,不上色三种情况,但是相邻的括号颜色不能相同,(可以同无色),每一对匹配的括号都有且仅有一个括号染色。
这题想了n久,今天做了半天终于给A掉了,感动得泪流满面。。。
题意不难理解,就是要想好久,开始没有思路,不知道如何做,然后偷偷看了一下别人的提示,说用dp[l][r][lc][rc]四维的数组来记录状态,于是就按这个思路,想了种方案,以为是那种很简单的dp,但是实际敲起来却发现各种都没考虑到。
这题的重点是一个串可能由多个匹配括号并列的,而且判断染色时得用到旁边的两个括号,递归时不好处理...
开始我没考虑到多个匹配括号并列,以为直接跟之前的dp题一样做就行了,结果跪了...现在看来这种想法够幼稚,这样只能判断((()))这样的括号串...
后来越来越想得用两个函数互相调用进行递归,但是处理状态记录想得头都大了...敲了好几个版本都跪了...
没办法了,看别人博客也没讲思路,瞥了一眼代码,看到了dfs的函数名,豁然开朗啊。。并确定一下人家只用了一个函数进行递归,于是我开始考虑把两个函数写在一块。
于是,不扯了,一下是思路:
先每对对括号进行记录。
dp的时候,当左右两边括号是匹配的时候,就为两个括号染色,然后就把状态转移到它们里面的括号串了
当不匹配的时候,也就是这个串是由多个匹配串并列而成的,那么就是dfs的思想了,为第一对括号染色,并求这对括号的子括号串的染色方案数,然后dp后面的那些串,直到dp到只剩一个串,并根据乘法原则把各种方案累计起来。(这样做是因为染色是和两边的括号颜色有关系的,而我们在dp前必须确定这个串两端的括号颜色。
递归的停止是当括号只有两个时,返回可能的染色数。
由于变量声明位置不对,结果wa了好几次,真是逗比...
代码:
几天做出一道这种题目,真是心情舒畅啊。。。
这题想了n久,今天做了半天终于给A掉了,感动得泪流满面。。。
题意不难理解,就是要想好久,开始没有思路,不知道如何做,然后偷偷看了一下别人的提示,说用dp[l][r][lc][rc]四维的数组来记录状态,于是就按这个思路,想了种方案,以为是那种很简单的dp,但是实际敲起来却发现各种都没考虑到。
这题的重点是一个串可能由多个匹配括号并列的,而且判断染色时得用到旁边的两个括号,递归时不好处理...
开始我没考虑到多个匹配括号并列,以为直接跟之前的dp题一样做就行了,结果跪了...现在看来这种想法够幼稚,这样只能判断((()))这样的括号串...
后来越来越想得用两个函数互相调用进行递归,但是处理状态记录想得头都大了...敲了好几个版本都跪了...
没办法了,看别人博客也没讲思路,瞥了一眼代码,看到了dfs的函数名,豁然开朗啊。。并确定一下人家只用了一个函数进行递归,于是我开始考虑把两个函数写在一块。
于是,不扯了,一下是思路:
先每对对括号进行记录。
dp的时候,当左右两边括号是匹配的时候,就为两个括号染色,然后就把状态转移到它们里面的括号串了
当不匹配的时候,也就是这个串是由多个匹配串并列而成的,那么就是dfs的思想了,为第一对括号染色,并求这对括号的子括号串的染色方案数,然后dp后面的那些串,直到dp到只剩一个串,并根据乘法原则把各种方案累计起来。(这样做是因为染色是和两边的括号颜色有关系的,而我们在dp前必须确定这个串两端的括号颜色。
递归的停止是当括号只有两个时,返回可能的染色数。
由于变量声明位置不对,结果wa了好几次,真是逗比...
代码:
#include <cstdio> #include <cstring> typedef long long LL; const int MAXN = 710; const LL MOD = 1e9 + 7; char str[MAXN]; int color[MAXN]; int w[4][2] = {{1, 0}, {0, 1}, {2, 0}, {0, 2}}; // 0: 无色 // 1: 红 // 2: 蓝 int f[MAXN][MAXN][4][4], match[MAXN]; int stk[MAXN], cnt; int dp(int l, int r) { LL sum = 0, pre, els; if (l == r - 1) { // check if (color[l - 1] != 1) sum++; if (color[l - 1] != 2) sum++; if (color[r + 1] != 1) sum++; if (color[r + 1] != 2) sum++; return sum; } if (match[l] == r) { for (int i = 0; i < 4; i++) { if (color[l - 1] == w[i][0] && w[i][0]) continue; if (color[r + 1] == w[i][1] && w[i][1]) continue; // dfs dp(l + 1, r - 1) color[l] = w[i][0]; color[r] = w[i][1]; if (!f[l + 1][r - 1][w[i][0]][w[i][1]]) f[l + 1][r - 1][w[i][0]][w[i][1]] = dp(l + 1, r - 1); sum += f[l + 1][r - 1][w[i][0]][w[i][1]]; sum %= MOD; } } else { // make sure of the first (*) and dfs the else for (int i = 0; i < 4; i++) { if (color[l - 1] == w[i][0] && w[i][0]) continue; // color first () color[l] = w[i][0]; color[match[l]] = w[i][1]; // pre = dp(l, match[l]) if (l == match[l] - 1) pre = 1; else { if (!f[l + 1][match[l] - 1][w[i][0]][w[i][1]]) f[l + 1][match[l] - 1][w[i][0]][w[i][1]] = dp(l + 1, match[l] - 1); pre = f[l + 1][match[l] - 1][w[i][0]][w[i][1]]; } // els = dp(match[l] + 1, r) if (!f[match[l] + 1][r][color[match[l]]][color[r + 1]]) f[match[l] + 1][r][color[match[l]]][color[r + 1]] = dp(match[l] + 1, r); els = f[match[l] + 1][r][color[match[l]]][color[r + 1]]; // ans = pre * els sum += pre * els; sum %= MOD; } } return sum; } int main() { gets(str + 1); int len = strlen(str + 1); // 预处理 for (int i = len; i >= 1; i--) if (str[i] == ')') stk[cnt++] = i; else match[i] = stk[--cnt]; printf("%d\n", dp(1, len)); return 0; }
几天做出一道这种题目,真是心情舒畅啊。。。
相关文章推荐
- 【CodeForces 149D】 【dp+dfs好题】D. Coloring Brackets【在限制条件下括号染色问题】
- CodeForces - 149D Coloring Brackets 详细题解(递归区间DP+dfs染色,好题)
- codeforces 149D Coloring Brackets (区间DP + dfs)
- CodeForces 149D Coloring Brackets(区间DP+dfs)
- FZU 2030 括号问题 dfs/dp
- codeforces 149D Coloring Brackets(区间dp)
- CodeForces 915C [DFS] CodeForces 158E [DP]
- 括号匹配问题 区间DP经典问题
- DP问题用dfs实现
- CodeForces 149D 区间DP Coloring Brackets
- uva10004 Bicoloring 黑白染色问题,DFS
- Codeforces 258B. Little Elephant and Elections【数位DP,DFS】
- UVA1218 Perfect Service(染色问题--树形DP)(好题,通法)
- CodeForces 293 B.Distinct Paths(dfs+状压DP)
- Codeforces 149D - Coloring Brackets(区间DP)
- dp:FZU2030括号问题
- POJ 1321 棋盘问题(DFS & 状压DP)
- CodeForces 149D Coloring Brackets(区间DP)
- 深度优先搜索(DFS)解决括号排列问题
- codeforces 743D Chloe and pleasant prizes (DFS/树形DP)