• [原]NYOJ 括号匹配系列2,5


    本文出自:http://blog.csdn.net/svitter


    括号匹配一:http://acm.nyist.net/JudgeOnline/problem.php?pid=2

    括号匹配二:http://acm.nyist.net/JudgeOnline/problem.php?pid=15


    之前被这个题目难住,现在看动态规划就顺便过来AC了它。结果发现当年被难住一点也不丢人。。

    括号匹配一很简单,就是栈的应用,AC代码:

    //============================================================================
    // Name        : 括号匹配.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <stack>
    
    using namespace std;
    
    void ace(){
    	int n;
    	scanf("%d", &n);
    	char ch;
    	char tmp;
    	ch = getchar();
    	while(n --){
    		stack <char> s;
    		while((ch = getchar())!= '
    '){
    			if(s.empty())
    				s.push(ch);
    			else{
    				tmp = s.top();
    				if(tmp == '(' && ch == ')')
    					s.pop();
    				else if(tmp == '[' && ch == ']')
    					s.pop();
    				else
    					s.push(ch);
    			}
    		}
    		if(s.empty())
    			printf("Yes
    ");
    		else
    			printf("No
    ");
    	}
    }
    
    
    int main() {
    	ace();
    	return 0;
    }
    第二道就是DP题目了- -

    真心被难住了。下面分析一下:

    通过分析(别问我怎么分析的,画多了就看出来了- -)这必定是一个通过区间括号求和计算出的最小匹配括号值。

    dp方程: dp [ i ] [ j ] = min ( dp [ i ] [ j ] , dp [ i ] [ k ] + dp [ k + 1 ] [ j ] );

    dp[ i ][ j ] 表示当前匹配最小的括号值。后来发现这个不是正确的- -。因为这个阶段值与另一个阶段值会相互影响,违反了条件。


    有重新做了分析:

    发现无非就是这么几种情况:

    " ..[ ... ] " + " ] “

    " ..[ ... [ " + " ] "

    " ..[ ... ] " + " [ "

    " ..[ ... [ " + " [ "

    这么四种情况。

    如果假设dp [ i ] [ j ] = dp [ i ] [ j - 1 ] + 1

    那么不符合情况的有第一种和第二种。而这两种情况就是因为中间串中有能够与最新加入的str[j]匹配的串。所以,当出现匹配串时,寻找最佳的匹配方案 ——dp [ i ] [ j ] = min ( dp [ i ] [ j ] , dp [ i ] [ k - 1 ] + dp [ k + 1 ] [ j - 1 ] );就是去除了两个括号,求括号里面的部分和括号外面部分的最小值。

    特别的,为了针对 j  == i + 1的情况, dp [ i ] [ j ] = min ( dp [ i ] [ j ], dp [ i + 1] [ k - 1 ] + dp [ k + 1 ] [ j ])是不成立的。

    AC代码:

    //============================================================================
    // Name        : 括号匹配.cpp
    // Author      :
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <stack>
    
    using namespace std;
    #define min(a, b) a > b ? b : a
    
    int dp[102][102];
    char str[1001];
    
    bool match(int i, int j)
    {
        if (str[i] == '(' && str[j] == ')')
            return true;
        else if (str[i] == '[' && str[j] == ']')
            return true;
        else
            return false;
    }
    
    void ace()
    {
        //case
        int c;
        scanf("%d", &c);
        getchar();
    
        //work point
        int i, j, k;
    
        //value
        int n;
    
        while (c--)
        {
            scanf("%s", str + 1); //此处可以尝试a+1
            memset(dp, 0, sizeof(dp));
            n = strlen(str + 1);
    
            //区间为差值为0时,必定需要一个括号匹配
            for (i = 1; i <= n; i++)
                dp[i][i] = 1;
    
            for (j = 2; j <= n; j++)        // j = 2...n
                for (i = j - 1; i >= 1; i--) // i = j...1
                {
                    dp[i][j] = dp[i][j-1] + 1;
                    for (k = i; k < j; k++)  //k = i+1...j-1
                    {
                        if(match(k, j))
                        {
                            dp[i][j] = min(dp[i][j], dp[i][k-1] + dp[k + 1][j - 1]);
                        }
                    }
                }
    
            printf("%d
    ", dp[1][n]);
        }
    }
    
    int main()
    {
        ace();
        return 0;
    }
    


    后来依据http://blog.csdn.net/svitter/article/details/25186367

    重写了代码,解题思路可以看上述题目。

    //============================================================================
    // Name        : test.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    //============================================================================
    // Name        : 动态规划.cpp
    // Author      : blog.csdn.net/svitter
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    #define MAXN 256
    char br[MAXN];
    int dp[MAXN][MAXN], pos[MAXN][MAXN];
    int len;
    
    bool match(int i, int j) {
    	if (br[i] == '(' && br[j] == ')')
    		return true;
    	if (br[i] == '[' && br[j] == ']')
    		return true;
    	return false;
    }
    
    int main() {
    	//work pit
    	int i, j, k, mid, t;
    	int Case;
    	scanf("%d", &Case);
    	getchar();
    	while (Case--) {
    		while (gets(br) != NULL) {
    			memset(dp, 0, sizeof(dp));
    
    			len = strlen(br);
    			for (i = 0; i < len; i++)
    				dp[i][i] = 1;
    
    			for (k = 1; k < len; k++) {
    				for (i = 0; i + k < len; i++) {
    					j = i + k;
    					dp[i][j] = 0x7fffffff;
    					if (match(i, j)) { //如果当前位置匹配,那么pos置-1
    						dp[i][j] = dp[i + 1][j - 1], pos[i][j] = -1;
    					}
    					for (mid = i; mid < j; mid++) {
    						if (dp[i][j] > (t = dp[i][mid] + dp[mid + 1][j])) { //如果存在更优分解,那么选择更优分解
    							dp[i][j] = t, pos[i][j] = mid;
    						}
    					}
    				}
    			}
    
    			printf("%d
    ", dp[0][len - 1]);
    		}
    	}
    
    	return 0;
    }
    


    作者:svitter 发表于2014-5-2 15:53:42 原文链接
    阅读:191 评论:0 查看评论
  • 相关阅读:
    js 将图片连接转换称base64格式
    mysql性能优化-慢查询分析、优化索引和配置
    MySQL集群(三)mysql-proxy搭建负载均衡与读写分离
    MySQL集群(二)之主主复制
    MySQL集群(一)之主从复制
    JavaSE(八)之Map总结
    JDBC(二)之JDBC处理CLOB和BLOB及事务与数据库元数据获取
    JavaSE(八)之Collection总结
    JavaSE集合(八)之Map
    JavaSE(八)之集合练习一
  • 原文地址:https://www.cnblogs.com/svitter/p/3724328.html
Copyright © 2020-2023  润新知