NYOJ15 - UVA1626 括号匹配问题(区间dp)
2014-05-06 12:52
489 查看
【题意】题目链接
NYOJ15 UVA1626
【分析】第一次学区间dp,看了别人的一个矩阵链乘后来做的http://www.jtben.com/document/1255647;这里的括号匹配和矩阵链乘类似的,具体看我的详细注释吧
【NYOJ15递推AC代码】8ms
【NYOJ15记忆化搜索AC代码】 4ms
【UVA1626打印方案】1029ms
NYOJ15 UVA1626
【分析】第一次学区间dp,看了别人的一个矩阵链乘后来做的http://www.jtben.com/document/1255647;这里的括号匹配和矩阵链乘类似的,具体看我的详细注释吧
【NYOJ15递推AC代码】8ms
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAXN 110 #define INF 0x3f3f3f3f char c[MAXN]; int dp[MAXN][MAXN];//dp[i][j]表示区间i~j的字符串中,最少的添加括号数量 int main () { #ifdef SHY freopen("e:\\1.txt", "r", stdin); #endif int t; scanf ("%d%*c", &t); while(t--) { gets(c); int n = strlen(c); memset(dp,0,sizeof(dp));//当不需要添加任何括号的时候,需要用到 for (int i = 0; i < n; i++)//初始化i==j的情况需要添加一个括号,也就是边界 dp[i][i] = 1; for (int m = 1; m < n; m++)//i和j的距离,也就是dp[]的对角线开始计算 { for (int i = 0; i < n-m; i++)//开始位置i { int j = i+m; dp[i][j] = INF;//初始化为最大值,或者直接调用min(dp[i][i], dp[i][i]+dp[i+1][j]); if (('(' == c[i] && ')' == c[j]) || ('[' == c[i] && ']' == c[j]))//保证[()]的情况不会被添加 dp[i][j] = min(dp[i][j], dp[i+1][j-1]); for (int k = i; k < j; k++)//把i~j分割为i~k和k+1~j,求怎样分割是最小值 dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]); } } printf ("%d\n", dp[0][n-1]); } return 0; }
【NYOJ15记忆化搜索AC代码】 4ms
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAXN 110 #define INF 0x3f3f3f3f int dp[MAXN][MAXN], n; char c[MAXN]; //dp[i][j]表示区间i~j之间添加的最少的括号数 int dfs(int i, int j) { if (-1 != dp[i][j])//记忆化 return dp[i][j]; if (i > j)//边界处理,不存在的可能,直接返回0 return dp[i][j] = 0; if (i == j)//只有一个括号的时候 return dp[i][j] = 1; int ans = dfs(i,j-1)+1;//如果下面i~j-1没有与j匹配的括号就添加一个 for (int k = i; k < j; k++)//枚举i~j-1,是否有与j匹配的括号 { //如果有匹配的括号,那么当前k位置需要添加的括号数为dfs(i,k-1)+dfs(k+1,j-1) if (('(' == c[k] && ')' == c[j]) ||( '[' == c[k] && ']' == c[j])) ans = min(ans, dfs(i,k-1)+dfs(k+1,j-1)); } return dp[i][j] = ans; } int main () { #ifdef SHY freopen("e:\\1.txt", "r", stdin); #endif int t; scanf ("%d%*c", &t); while(t--) { gets(c); n = strlen(c); memset(dp,-1,sizeof(dp)); printf ("%d\n", dfs(0,n-1)); } return 0; }
【UVA1626打印方案】1029ms
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAXN 110 char a[MAXN]; int dp[MAXN][MAXN]; void pt(int i, int j) { if (i > j) return; if (i == j) { if ('(' == a[i] || ')' == a[i]) printf("()"); else printf("[]"); return; } if ((('(' == a[i] && ')' == a[j]) || ('[' == a[i] && ']' == a[j])) && dp[i][j] == dp[i + 1][j - 1]) { printf("%c", a[i]); pt(i+1,j-1); printf("%c", a[j]); return; } for (int k = i; k < j; k++) { if (dp[i][j] == dp[i][k] + dp[k + 1][j]) { pt(i, k), pt(k + 1, j); return; } } } int main() { #ifdef SHY freopen("e:\\1.txt", "r", stdin); #endif int t; scanf("%d%*c%*c", &t); while (t--) { gets(a); getchar(); int n = strlen(a); memset(dp,0x3f,sizeof(dp)); for (int i = 0; i < n; i++) dp[i][i] = 1, dp[i+1][i] = 0; for (int i = n - 2; i >= 0; i--) { for (int j = i + 1; j < n; j++) { if (('(' == a[i] && ')' == a[j]) || ('[' == a[i] && ']' == a[j])) dp[i][j] = min(dp[i][j], dp[i+1][j-1]); for (int k = i; k < j; k++) dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]); } } pt(0,n-1); printf("\n"); if (t) puts(""); } return 0; }
相关文章推荐
- NYOJ15 - UVA1626 括号匹配问题(dp)
- nyoj 15 括号匹配(二)(区间DP)
- NYOJ 15 括号匹配(二) POJ 2955 Brackets(区间dp)
- NYOJ 15 括号匹配(二)(区间dp)
- 【区间DP】NYOJ 737石子合并+POJ 2955 Brackets(括号匹配)+NYOJ 15 括号匹配(二)
- nyoj 15 括号匹配(二)(区间DP)
- nyoj 15 括号匹配(二)(区间DP)
- NYOJ 15 括号匹配(区间dp)
- nyoj 15 括号匹配(二)(区间DP)
- NYOJ 15 括号匹配(二)区间dp
- nyoj 括号匹配(二) 15 (区间dp) 好题
- NYOJ_15_括号匹配(二)【区间DP】
- nyoj 15 括号匹配(二)(区间DP)
- NYOJ15-括号匹配(二)-区间DP
- nyoj 15 括号匹配(二)(区间DP)
- UVA1626 - Brackets sequence(区间DP--括号匹配+递归打印)
- nyoj 15 括号匹配(二)(区间DP)
- nyoj 15 括号匹配(二)(区间DP)
- UVA 1626 Brackets sequence(括号匹配 + 区间DP)
- nyoj 15 括号匹配(二)(区间DP)