动态规划训练10 [Coloring Brackets CodeForces - 149D]

西安交大 软件53 蔡少斐 整理

Coloring Brackets

 CodeForces - 149D 


题目大意:

给定合法的括号序列,让你给括弧上色,并且上色时一定要满足3个要求:

(1)每个括号要么被上红色,要么被上蓝色,要么不上色。

(2)一对匹配的左右括弧,有且只有其中的一个可以被上色。

(3)相邻的括弧不能被涂上相同的颜色。


这道题也是很明显的区间DP问题,遗憾的是,我一开始没有想到怎么dp。


首先我们要进行预处理,求出每个括号的唯一配对的括号,即寻找他们一一对应的关系,这个预处理很简单,用栈操作一下就可以了

预处理代码:

gets(str);stack<int> stk;int len = strlen(str);for(int i = 0;i < len;i++){if(str[i] == '('){stk.push(i);}else{int p = stk.top();stk.pop();mp[p] = i;mp[i] = p;}}

下面我们考虑的区间,全部都是配对合法的区间!

用一个四维数组dp[l][r][i][j]表示区间[l,r]且l处被涂上i色,r处被涂上j色。(规定无色为0,红色为1,蓝色为2)

那么我们可以得到下面的状态转移方程:

(1)当区间长度只有2时候(两个括弧一定是配对的,因为我们考虑的所有区间都是配对合法的区间),上色方案是非常好确定的。

dp[l][r][0][1] = 1;
dp[l][r][0][2] = 1;
dp[l][r][1][0] = 1;
dp[l][r][2][0] = 1;

(2)当区间的左右括弧是配对的时候(判断左右括弧是否匹配,用到了预处理得到的结果)。则有如下转移方法:

if(j != 1)
dp[l][r][0][1] = (dp[l][r][0][1] + 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 != 1)
dp[l][r][1][0] = (dp[l][r][1][0] + 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;

(3)当区间非左右配对时,把区间划分为左右两个各自合法 的区间,转移方程是。

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

这里注意k代表的是与l配对的括号,那么k+1就是与r配对的括号了。(这就是预处理的作用!)


而在动态规划的实现过程中,我们发现并非所有的区间都是合法的,只有少部分的区间是合法的,因此我们用自顶向下的记忆化dp的方法,这样可以简化代码的实现。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
#define int long long 
using namespace std;
const int MAX = 705;
const int MOD = 1e9 + 7;
int used[MAX][MAX];
int mp[MAX];
char str[MAX];
int dp[MAX][MAX][3][3];
void dfs(int l,int r){if(used[l][r]) return ;used[l][r] = 1;if(l + 1 == r){dp[l][r][0][1] = 1;dp[l][r][0][2] = 1;dp[l][r][1][0] = 1;dp[l][r][2][0] = 1;return ;}if(mp[l] == r){//配对的情况 dfs(l+1,r-1);for(int i = 0;i < 3;i++){for(int j = 0;j < 3;j++){if(j != 1)dp[l][r][0][1] = (dp[l][r][0][1] + 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 != 1)dp[l][r][1][0] = (dp[l][r][1][0] + 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;	}}}else{int k = mp[l];dfs(l,k);dfs(k+1,r);for(int i = 0;i < 3;i++){for(int j = 0;j < 3;j++){for(int p = 0;p < 3;p++){for(int q = 0;q < 3;q++){if(p + q == 0 || p != q ){dp[l][r][i][j] = (dp[l][r][i][j] + dp[l][k][i][p] * dp[k+1][r][q][j]%MOD)%MOD;}}} }} }
}
main(){gets(str);stack<int> stk;int len = strlen(str);for(int i = 0;i < len;i++){if(str[i] == '('){stk.push(i);}else{int p = stk.top();stk.pop();mp[p] = i;mp[i] = p;}}dfs(0,len-1);int ans = 0;for(int i = 0;i < 3;i++){for(int j = 0;j < 3;j++){ans = (ans + dp[0][len-1][i][j])%MOD;}}cout<<ans<<endl;return 0;
} 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软重组变两大事业部:Windows主管离职

微软CEO纳德拉通过内部邮件宣布&#xff0c;整个公司进行重大重组&#xff0c;划分为两个新的事业部(部门)&#xff0c;同时Windows业务主管Terry Myerson(特里梅尔森)将离开微软。Terry Myerson最为人诟病的就是推倒了Windows Mobile而打造全新的Windows Phone&#xff0c;结果…

jzoj3846-七天使的通讯【二分图判定】

正题 题目链接:https://jzoj.net/senior/#main/show/3846 题目大意 长度nnn的直线&#xff0c;mmm条线&#xff0c;将它们分成两边&#xff0c;使同一边不交叉&#xff0c;求是否有方案。 解题思路 将会交叉的直线之间连接边&#xff0c;然后判断是否是二分图即可。 codecod…

41、java应用占用cpu过高原因分析

线上服务器cpu占用过高问题排查 1、定位最耗cpu的进程 命令&#xff1a;top 2、定位最耗cpu的线程 命令&#xff1a;Top –Hp PID 例如&#xff1a;Top –Hp 12086 3、打印线程堆栈信息 命令&#xff1a;Printf ‘%x\n’ PID 例如&#xff1a;printf ‘%x\n’ 12118 先将…

动态规划训练11 [String painter HDU - 2476]

String painter HDU - 2476 题意&#xff1a; 我认为这是一道比较难的问题&#xff0c;自己想了很久&#xff0c;没有想出来怎么做&#xff0c;可能是因为思维僵化吧&#xff0c;一直在想怎么直接的由A变到B&#xff0c;事实上&#xff0c;可以有中间桥梁连接A和B&#xff0c;…

Google Optimization Tools介绍

Google Optimization Tools(OR-Tools)是一款专门快速而便携地解决组合优化问题的套件。它包含了&#xff1a;约束编程求解器。简单而统一的接口&#xff0c;用于多种线性规划和混合整数规划求解&#xff0c;包括 CBC、CLP、GLOP、GLPK、Gurobi、CPLEX 和SCIP。图算法 (最短路径…

11、mysql数据表中数据的查询(3)

说一下子查询&#xff0c;子查询的意义就是使用一个查询语句做为另一个查询语句的条件&#xff0c;一般使用exists和in来引导子查询 exists子查询 exists 放在 where 之后使用&#xff0c;可以看成查询数据所满足的一个条件&#xff0c;只是这个条件的值比较特殊&#xff08;…

jzoj3847-都市环游【矩阵乘法】

正题 题目链接:https://jzoj.net/senior/#main/show/3847 题目大意 nnn个点mmm条边&#xff0c;第iii个点要求hih_ihi​时才可以到达。求经过ttt时从点1到点nnn的方案数。 解题思路 因为hih_ihi​较小&#xff0c;设zi,kz_{i,k}zi,k​表示iii时到kkk的方案数&#xff0c;转移…

使用.Net Core与Google Optimization Tools实现员工排班计划Scheduling

上一篇说完《Google Optimization Tools介绍》&#xff0c;让大家初步了解了Google Optimization Tools是一款约束求解&#xff08;CP&#xff09;的高效套件。那么我们用.Net Core与Google Optimization Tools来实现一个有关员工排班计划的场景感受一下。众所周知&#xff0c;…

动态规划训练12 [G - You Are the One HDU - 4283 ]

2012天津区域赛的一道题目&#xff0c;题目链接如下 You Are the One HDU - 4283 这道题目要说思想的话其实并不是很难&#xff0c;但是我却没做出来。关键就在于读题读不懂&#xff08;How Vegetable I am&#xff01;&#xff09;&#xff0c;到最后搜了别人的题解才明白这道…

42、Java服务内存OOM原因分析

1、出现问题的可能原因 对于应用来说内存分配太少 对象创建太多&#xff0c;又没有释放&#xff0c;造成内存泄漏严重&#xff0c;导致内存耗尽 申请太多的系统资源&#xff0c;系统资源耗尽。例如&#xff1a;不断创建线程&#xff0c;不断发起网络连接 2、如何定位问题&a…

jzoj3850-Fibonacci进制【斐波那契倍增】

正题 题目大意:https://jzoj.net/senior/#main/show/3850 题目大意 定义f(i)f(i)f(i)表示第i1i1i1个斐波那契数 一个数转换成斐波那契进制后第iii位的0/10/10/1表示是否需要加上f(i)f(i)f(i)&#xff0c;然后将1∼∞1\sim \infty1∼∞转换成斐波那契进制后依次输出在屏幕上&a…

Slickflow.NET 开源工作流引擎基础介绍-.NET Core2.0 版本实现介绍

前言&#xff1a;.NET Core 是.NET Framework的新一代版本&#xff0c;是微软开发的第一个跨平台 (Windows、Mac OSX、Linux) 的应用程序开发框架&#xff08;Application Framework&#xff09;&#xff0c;未来也将会支持 FreeBSD 与 Alpine 平台。.Net Core也是微软在一开始…

动态规划训练13 [Catch That Cow poj3278]

Catch That Cow POJ - 3278 这道题我看大家用的方法都是bfs搜索&#xff0c;为什么在我看来这就是一个动态规划的题目啊啊啊啊啊啊啊 dp[x]表示从N出发到x所需要的最小时间 那么得到如下转移方程 如果x < N的话&#xff0c;那么只能通过走路来转移&#xff0c;所以dp[x] …

jzoj1246-挑剔的美食家【set,贪心】

正题 题目大意:https://jzoj.net/senior/#main/show/1246 题目大意 nnn头牛&#xff0c;第iii头吃的东西价格大于aia_iai​&#xff0c;鲜嫩度大于bib_ibi​。mmm个吃的&#xff0c;第iii个价格为cic_ici​&#xff0c;鲜嫩度为did_idi​。 求满足所有奶牛的情况下最少要花多少…

DotNetty 跨平台的网络通信库

久以来,.Net开发人员都非常羡慕Java有Netty这样&#xff0c;高效&#xff0c;稳定又易用的网络通信基础框架。终于微软的Azure团队&#xff0c;使用C#实现的Netty的版本发布。不但使用了C#和.Net平台的技术特点&#xff0c;并且保留了Netty原来绝大部分的编程接口。让我们在使用…

26、临时表的创建和重复数据的处理

UPDATE student b SET b.sname dd WHERE b.id (SELECT a.id FROM student a WHERE a.id 3) Mysql中根据条件&#xff08;表A中的字段&#xff09;操作表A中的数据时是不可以的 所以借助临时表来删除/更新重复的数据&#xff0c;原理就是删除每组重复数据中除id值最大的其他…

动态规划训练14 [Max Sum Plus Plus HDU - 1024 ]

Max Sum Plus Plus HDU - 1024 题意大致是说给你你个序列&#xff0c;把它划分成不相交的几个连续的部分&#xff0c;然后把这个几个部分求和&#xff0c;求出和的最大值。 我们定义子结构 dp[i][j] 表示的是从前j个元素&#xff0c;划分成i段所得的最大和。 则我们可以得到…

jzoj1247-队列变换【字符串hash,二分】

正题 题目链接:https://jzoj.net/senior/#main/show/1247 题目大意 一个长度为nnn的字符串&#xff0c;每次选择头或者尾加入新的字符串末端&#xff0c;求字典序最小的新的字符串。 解题思路 我们发现若剩下的字符串比翻转之后份字符串字典序大那么就加入头&#xff0c;否则…

1、java简介

关于java介绍也没什么好说的&#xff0c;在这里简单介绍一下&#xff0c;说起java&#xff0c;我第一想到的就是它的简单和强大&#xff0c;简单是简单易学&#xff0c;开发速度快&#xff1b;强大是其功能强大&#xff0c;各个领域都可使用&#xff0c;其代码一次编译可以处处…

C# 观察者模式 以及 delegate 和 event

观察者模式这里面综合了几本书的资料.需求有这么个项目: 需求是这样的:一个气象站, 有三个传感器(温度, 湿度, 气压), 有一个WeatherData对象, 它能从气象站获得这三个数据. 还有三种设备, 可以按要求展示气象站的最新数据.WeatherData的结构如下:有3个get方法, 分别获取最新的…