POJ 1141 Brackets Sequence (DP)
2015-08-25 14:03
501 查看
最初看这个问题,有些困惑,不是对每个没配对上的括号补齐括号就可以了吗。不过没这么简单,如果只有一种括号,不同的补齐方法,都只需要补齐相同数目的括号。而这里有两种括号,在交错的情况下,不同的补齐方法,需要补齐的扩号数可能不一样。看下面的例子:
[[(]])
补齐方法:
[[()]]()
[[]]([][])
......
这个问题要求我们找出,需要补齐的括号数最少的方法之一(Special Judge)。
搞清题意之后,再来看这个问题。可以用DP来解答。
令 dp[i][j] 表示输入串在[i,j]这一段需要补齐的最少括号数,有
(1) 若in[i]和in[j]匹配括号,取dp[i][j] = dp[i+1][j-1] 记 k=-1
(2) 其他可能的情况:dp[i][j] = dp[i][k] + dp[k+1][j] (i=<k<j)
那么 dp[i][j] = Min{(1), (2)},另外用path[i][j]记住每一步选择的k值,以输出最优解。
[[(]])
补齐方法:
[[()]]()
[[]]([][])
......
这个问题要求我们找出,需要补齐的括号数最少的方法之一(Special Judge)。
搞清题意之后,再来看这个问题。可以用DP来解答。
令 dp[i][j] 表示输入串在[i,j]这一段需要补齐的最少括号数,有
(1) 若in[i]和in[j]匹配括号,取dp[i][j] = dp[i+1][j-1] 记 k=-1
(2) 其他可能的情况:dp[i][j] = dp[i][k] + dp[k+1][j] (i=<k<j)
那么 dp[i][j] = Min{(1), (2)},另外用path[i][j]记住每一步选择的k值,以输出最优解。
#include <iostream> #include <string.h> using namespace std; char in[101]; int dp[101][101]; // least brackets to be added between in[i, j] int path[101][101]; // break point of dp[i][j] void getMinRegularSeq(int len) { memset(dp, -1, sizeof(dp)); memset(path, -1, sizeof(path)); // dp bottom-up for (int i = len-1; i >= 0; --i) { for (int j = i; j < len; ++j) { if (i == j) { dp[i][j] = 1; path[i][j] = i; continue; } if ( (in[i] == '(' && in[j] == ')') || (in[i] == '[' && in[j] == ']')) { path[i][j] = -1; if (j-i > 1) { dp[i][j] = dp[i+1][j-1]; } else { dp[i][j] = 0; continue; // least already } } for (int k = i; k < j; ++k) { if (dp[i][j] == -1 || dp[i][k]+dp[k+1][j] < dp[i][j]) { dp[i][j] = dp[i][k]+dp[k+1][j]; path[i][j] = k; } } } } } void printMinRegularSeq(int l, int r) { if (l > r) return; if (l == r) { if (in[l] == '(' || in[l] == ')') cout << "()"; if (in[l] == '[' || in[l] == ']') cout << "[]"; } else { if (path[l][r] == -1) { cout << in[l]; printMinRegularSeq(l+1,r-1); cout << in[r]; } else { printMinRegularSeq(l, path[l][r]); printMinRegularSeq(path[l][r]+1, r); } } } int main(int argc, char** argv) { cin.getline(in, 101); int len = strlen(in); if (len > 0) { getMinRegularSeq(len); printMinRegularSeq(0, len-1); } cout << endl; return 0; }
相关文章推荐
- leetcode 之 Unique Paths
- 关于android uid 与进程的关系
- POJ 1788 Building a New Depot(水~)
- iOS 并发编程之 Operation Queues
- UITableView的registerClass forCellReuseIdentifier用法详解
- UI第二讲UITextField和UIButton
- 报错: Access restriction:The type JPEGCodec is not accessible due to restriction on required library
- 关于Qt5 使用QQuickWidget加载QML背景设置透明的问题!
- 动态修改ui2dsprite的图片
- rpmbuild打包qwt
- UI第一讲UIView和UILabel
- SVN问题: configure: error: subversion requires zlib
- ueditor 结合easyui使用
- scu oj 4443 Range Query (scoure :2015年四川省acm省赛)
- 如何对使用了autolayout的UIView添加动画
- MySQL Query Cache
- 理解Automatically selecting local only mode for query本地模式
- Ubuntu编译openwrt时出现Parser perl module is required for intltool 问题
- svn error:Subversion requires SQLite解决
- 部署XenMobile并与XenDesktop集成 - Citrix Workspace Suite