【bzoj4350】括号序列再战猪猪侠 区间DP
来源:互联网 发布:linux平台安装mongodb 编辑:程序博客网 时间:2024/06/09 17:15
Description
括号序列与猪猪侠又大战了起来。
众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号
序列S合法,当且仅当:
1.( )是一个合法的括号序列。
2.若A是合法的括号序列,则(A)是合法的括号序列。
3.若A,B是合法的括号序列,则AB是合法的括号序列。
我们考虑match[i]表示从左往右数第i个左括号所对应的是第几个右
括号,现在他得到了一个长度为2n的括号序列,给了你m个信息,第i
个信息形如ai,bi,表示match[ai]
Input
第一行一个正整数T,T< = 5,表示数据组数。
对于每组数据,第一行一个n,m,n表示有几个左括号,m表示信息数。
接下来m行,每行两个数ai,bi,1< = ai,bi< = n。
Output
对于每组数据,输出一个数表示答案。
Sample Input
51 05 03 21 22 33 22 12 33 31 22 33 1
Sample Output
142120
HINT
对于前两个点,是卡特兰数的情况。
对于第三个点,合法的情况只可能是 ()()()。
对于第四个点,合法情况可能是 (()()) 或者 (())()
对于第五个点,由于拓扑关系形成了环,显然无解。
对于 100% 的数据,保证 n < = 300
Source
ydc给我们的考试题…T1…………
ydc:这道题是本场考试最水的
具体做法是区间dp,状态转移方程也挺好写,三种情况:()AB,(AB),(A)B。
重点在如何处理【i的右括号必须在j的右括号左边】这个约束。
二维前缀和。sum[i][j]为1表示i必须在j之前。考虑一个矩形所代表的含义:
先考虑边长为1的矩形。矩形((a,b),(a,c))的权值若是1,则表示a必须在b~c中某个的前面。若为0,则表示a没必要在b~c的任意一个数左边,也就是a的右括号可以放c后面或者b前面。
我们发现矩形权值为0的性质可以利用。考虑((a,b),(c,d))的含义:若权值为0,则表示a~c中任意一个元素对于b~d中任意一个元素都没有条件约束。这个性质可以快速查询一个括号序列是否可以在另一个括号序列之前。
状态dp[i][j]表示第i个左括号到第j个左括号组成的括号序列方案数,然后根据二维前缀和查询DP就行了…
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int SZ = 500;const int mod = 998244353;int dp[SZ][SZ];int sum[SZ][SZ];int getsum(int a,int b,int c,int d){ return sum[c][d] - sum[c][b - 1] - sum[a - 1][d] + sum[a - 1][b - 1];}int ask(int n){ for(int i = 1;i <= n;i ++) if(getsum(i,i,i,i)) return 0; for(int i = n;i >= 1;i --) { dp[i][i] = 1; for(int j = i + 1;j <= n;j ++) { if(!getsum(i,i + 1,i,j)) //(AB) dp[i][j] = (dp[i][j] + dp[i + 1][j]) % mod; if(!getsum(i + 1,i,j,i)) //()AB dp[i][j] = (dp[i][j] + dp[i + 1][j]) % mod; for(int k = i + 1;k < j;k ++) //(A)B if(!getsum(i,i + 1,i,k) && !getsum(k + 1,i,j,i) && !getsum(k + 1,i + 1,j,k)) dp[i][j] = (dp[i][j] + (LL)dp[i + 1][k] * dp[k + 1][j] % mod) % mod; } } return dp[1][n];}void init(){ memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum));}int main(){ int T; scanf("%d",&T); while(T --) { init(); int n,m; scanf("%d%d",&n,&m); for(int i = 1;i <= m;i ++) { int x,y; scanf("%d%d",&x,&y); sum[x][y] = 1; } for(int i = 1;i <= n;i ++) for(int j = 1;j <= n;j ++) sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1]; printf("%d\n",ask(n)); } return 0;}
- 【bzoj4350】括号序列再战猪猪侠 区间DP
- BZOJ4350: 括号序列再战猪猪侠(区间DP)
- 【区间dp】括号序列再战猪猪侠
- 括号序列 区间DP
- [区间DP 思路题] BZOJ 4350 括号序列再战猪猪侠
- 区间DP(括号序列,uva1626)
- UVA 1626 括号序列(区间dp)
- CodeVS3657 括号序列 解题报告【区间DP】
- 【基础练习】【区间DP】codevs3657 括号序列题解
- UVa 1626 括号序列——区间DP
- 区间dp括号匹配
- poj1141 括号序列 dp
- dp uva1626 括号序列
- poj2955,括号匹配,区间dp
- nyoj+区间dp括号匹配
- poj2955Brackets【区间dp 括号匹配】
- uestc 1546 括号序列 区间线段树
- 3295: 括号序列 -(序列DP)
- 人人网移动开发架构
- 给Eclipse提速的7个技巧
- Apache Commons工具集简介
- android应用程序启动解决黑屏及全屏显示时因数据加载缓慢出现标题栏问题解决
- Eclipse项目分包管理
- 【bzoj4350】括号序列再战猪猪侠 区间DP
- innodb锁(三)
- Android逆向---Fiddler简易使用教程之抓取https包
- 去除UITableView底部多余行及分割线
- PRVF-5636 : The DNS response time for an unreachable node exceeded "15000" ms on following nodes
- Android之Glide获取图片Path、Bitmap用法
- Mysql字符集设置
- 一步一步开发安卓应用 手机端网上购物系统
- 【转】方便好使的java.util.Properties类