• 洛谷 题解 UVA1626 【括号序列 Brackets sequence】


    看还没有人发记搜的题解,赶紧来发一篇

    我们定义dp[i][j]为区间i~j内最少添加几个括号才能把这个串变成正规括号序列。

    考虑四种情况

    1. i>j不存在这种子串,返回0

    2. i==j子串长度为1无论是"[","]","(",")"都是要消耗1的,返回1

    3. s=(s')或s=[s']那么返回的是DP(i+1,j-1)

    4. 其他情况,枚举断点,详见代码

    至于输出嘛.....不会,看紫书的,输出代码的解释看看楼上吧,这里就不详细解释了

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int INF=0x3f3f3f3f;
    int T,n;
    string s;
    int dp[110][110];//记忆
    inline int DP(int l,int r)//记搜
    {
    	if(l==r)return dp[l][r]=1;//②
    	if(l>r)return dp[l][r]=0;//①
    	if(dp[l][r]!=INF)return dp[l][r];//记忆化
    	if(s[l-1]=='('&&s[r-1]==')'||s[l-1]=='['&&s[r-1]==']')dp[l][r]=min(dp[l][r],DP(l+1,r-1));//③
    	for(int i=l;i<r;i++)//枚举i~j的断点
    	{
    		dp[l][r]=min(dp[l][r],DP(l,i)+DP(i+1,r));//④
    	}
    	return dp[l][r];
    }
    inline void print(int l,int r)//输出
    {
    	if(l>r)return;
    	if(l==r)
    	{
    		if(s[l-1]=='('||s[l-1]==')')
    			cout<<"()";
    		if(s[l-1]=='['||s[l-1]==']')
    			cout<<"[]";
    		return;
    	}
    	if(dp[l][r]==dp[l+1][r-1]&&((s[l-1]=='('&&s[r-1]==')')||(s[l-1]=='['&&s[r-1]==']')))
    	{
    		cout<<s[l-1];
    		print(l+1,r-1);
    		cout<<s[r-1];
    	}
    	else
    	{
    		for(int i=l;i<r;i++)
    		{
    			if(dp[l][r]==dp[l][i]+dp[i+1][r])
    			{
    				print(l,i);
    				print(i+1,r);
    				return;
    			}
    		}
    	}
    }
    int main()
    {
    	scanf("%d",&T);
    	getchar();
    	while(T--)
    	{
    		memset(dp,0x3f,sizeof(dp));
    		getline(cin,s);
            getline(cin,s);
         //这里要小心,输入的可能是空串!!!!!!!!坑了我很久了
            int n=s.size();
            //cout<<n<<" "<<s<<endl;
            if(!n)
            {
                cout<<endl<<endl;
                continue;
            }
    		DP(1,n);
    		//cout<<DP(1,n)<<endl;
    		print(1,n);
    		cout<<endl;
    		if(T)cout<<endl;//输出格式也要注意!!
    	}
    	return 0;
    }
    
  • 相关阅读:
    mybatis框架查询用户表中的记录数
    文件的上传和下载
    怎样在一条sql语句中将第一列和第二列加和的值作为第三列的值
    [OS] 进程的虚地址空间
    [网络] TCP/IP协议族各层的协议汇总
    [面试] C++ 虚函数表解析
    [OS] 堆栈、堆、数据段、代码段
    [算法] 并查集概念及其实现
    [OS] 我与大牛的对话!
    [C] int *p[4]与int (*q)[4]的区别
  • 原文地址:https://www.cnblogs.com/hulean/p/10902633.html
Copyright © 2020-2023  润新知