Codeforces Round #343 (Div. 2)C. Famil Door and Brackets DP
2016-02-27 11:13
387 查看
转自:Codeforces Round #343 (Div. 2) 解题报告
题意:给你一个由括号组成的字符串,长度为m,现在希望获得一个长度为n(全由括号组成)的字符串,0<=n-m<=2000
这个长度为n的字符串要求有两个性质:
现在让你可以在长度为m的原串前加一个括号串p,在原串后加一个括号串q 最后p+m+q=n
问有多少种组合p,q能得到目标串
题目思路:
定义dp[i][j],为前缀长为i,且左括号数量-右括号数量=j的串有多少个
算出s段左括号与右括号的差值记为cnt,记录p段至少需要的左括号数目为need。
然后枚举p的长度和平衡值 对于长度i, 当-d<=j时,p可以加到前面
然后当p确定后,q的长度也确定,因为最终 左=右 ,所以q 的(右-左)的代价也知道了
假设当前是i,平衡度是j,所以只要将dp[i][j]*dp[n-m-i][j+cnt]加到答案就行了
注意:dp[i][j]代表前缀i,平衡度为j的方案数, dp[n-m-i][j+cnt]为后缀n-m-i,平衡度为-(j+cnt)的方案数,是对称的,很重要
即:dp[n - m - i][j + cnt] = dp[n - m - i][-(j + cnt)] // dp第二维不可为负数
题意:给你一个由括号组成的字符串,长度为m,现在希望获得一个长度为n(全由括号组成)的字符串,0<=n-m<=2000
这个长度为n的字符串要求有两个性质:
就是任意前缀,左括号数量大于右括号数量 字符串中左括号的数量等于右括号
现在让你可以在长度为m的原串前加一个括号串p,在原串后加一个括号串q 最后p+m+q=n
问有多少种组合p,q能得到目标串
题目思路:
定义dp[i][j],为前缀长为i,且左括号数量-右括号数量=j的串有多少个
算出s段左括号与右括号的差值记为cnt,记录p段至少需要的左括号数目为need。
然后枚举p的长度和平衡值 对于长度i, 当-d<=j时,p可以加到前面
然后当p确定后,q的长度也确定,因为最终 左=右 ,所以q 的(右-左)的代价也知道了
假设当前是i,平衡度是j,所以只要将dp[i][j]*dp[n-m-i][j+cnt]加到答案就行了
注意:dp[i][j]代表前缀i,平衡度为j的方案数, dp[n-m-i][j+cnt]为后缀n-m-i,平衡度为-(j+cnt)的方案数,是对称的,很重要
即:dp[n - m - i][j + cnt] = dp[n - m - i][-(j + cnt)] // dp第二维不可为负数
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; typedef long long LL; const int maxn = 2010; const int mod = 1e9 + 7; const int INF = 10000000000; int N, M; char s[100010]; LL dp[maxn][maxn]; void add(LL &a, LL b) { a += b; if (a >= mod) { a -= mod; } } int main() { scanf("%d%d",&N,&M); scanf("%s",s+1); memset(dp,0,sizeof(dp)); dp[0][0] = 1; for (int i = 1; i <= N - M; i++) { for (int j = 0; j <= i; j++) { add(dp[i][j],dp[i-1][j+1]); if (j > 0) { add(dp[i][j],dp[i-1][j-1]); } } } int minv = INF; int num = 0; for (int i = 1; i <= M; i++) { if (s[i] == '(')num++; else num--; minv = min(minv,num); } LL ans = 0; for (int i = 0; i <= N - M; i++) { for (int j = 0; j <= i; j++) { if (j + minv >= 0 && j + num <= N - M - i) { add(ans,dp[i][j]*dp[N-M-i][j+num]%mod); } } } cout<<ans<<endl; return 0; }
相关文章推荐
- USB鼠标按键驱动
- Android手机号码归属地的查询(使用聚合数据API,获取JSON数据并解析)
- java IO 流Stream 序列化Serializable 文件File
- 机器学习算法选择
- 如何使域名跳转到个人博客
- 格式化数据#8: AIE实验室交流群推荐的相关书籍(附豆瓣链接和ISBN)
- 五年北京,这个改变我命运的城市,终于要离开了(转)
- power of n
- 在MFC单文档窗口中添加背景图片
- 【Cocos2d-x 001】VS2012打开Cocos解决方案显示加载失败
- 利用Tomcat建立多个Web Server的方法
- 分布式全局不重复ID生成算法
- typedef struct 和struct
- 【leetcode】【12】Integer to Roman
- 从一个简单的C语言程序分析计算机程序工作过程
- 第十五章 动态规划
- flume整合kafka
- TypedArray使用方法
- win7生成生成Detours.lib以及简单使用实例
- Android WIFI 启动流程(TIP^^)