• CF 1272F Two Bracket Sequences (括号dp)


    题目地址

    洛谷CF1272F

    Solution

    首先题目中有两个括号串 (s)(t) ,考虑先设计两维表示 (s) 匹配到的位置和 (t) 匹配到的位置。

    接着根据 括号dp的一般套路:设计一维表示当前栈中的左括号数量 (ygt大佬喜欢形象地把其称为 “前缀和”),所以状态就出来了:

    [f[i,j,k] exttt{表示 s 匹配到 i , t 匹配到 j , 栈中有 k 个左括号,的最小新序列长度} ]

    转移挺简单的,新序列要么增加一个 '(' , 要么增加一个 ')' , 直接转移即可。

    但是转移的阶段顺序很难写,但是 根据递推不好写我们就递归的原则 我们可以写一个 记忆化搜索。具体实现和路径输出请看代码。

    Code

    Talk is cheap.Show me the code.

    #include<bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    inline int read() {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    	while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    	return x * f;
    }
    const int N = 207;
    int n,m;
    int dp[N][N][N<<1];
    char s[N],t[N],op[N][N][N<<1];
    struct Node {
    	int x,y,z;
    }pr[N][N][N<<1];
    int Solve(int i,int j,int k) {
    	if(dp[i][j][k] != -1) return dp[i][j][k];
    	if(i==n+1 && j==m+1) return k;            //栈中还有k个左括号,我们要k个右括号与之匹配
    	int res1 = INF, res2 = INF, ni1 = ((i<=n&&s[i]=='(')?i+1:i), nj1 = ((j<=m&&t[j]=='(')?j+1:j), ni2 = ((i<=n&&s[i]==')')?i+1:i), nj2 = ((j<=m&&t[j]==')')?j+1:j);
    	if(k <= 200) res1 = Solve(ni1,nj1,k+1) + 1;
    	if(k > 0) res2 = Solve(ni2,nj2,k-1) + 1;
    	if(res1 < res2) {
    		op[i][j][k] = '('; dp[i][j][k] = res1; pr[i][j][k] = (Node)<%ni1,nj1,k+1%>;
    	} else {
    		op[i][j][k] = ')'; dp[i][j][k] = res2; pr[i][j][k] = (Node)<%ni2,nj2,k-1%>;
    	}
    	return dp[i][j][k];
    }
    void Print(int i,int j,int k) {
    	Node tmp = pr[i][j][k];
    	if(op[i][j][k]=='(' || op[i][j][k]==')') cout<<op[i][j][k];
    	if(tmp.x!=-1) Print(tmp.x, tmp.y, tmp.z);
    	else {
    		for(int l=1;l<=k;++l) cout<<')';    //输出这k个右括号
    	}
    }
    int main()
    {
    	//freopen("My.out","w",stdout);
    	scanf("%s%s",s+1,t+1);
    	n = strlen(s+1), m = strlen(t+1);
    	memset(dp, -1, sizeof(dp));
    	memset(pr, -1, sizeof(pr));
    	Solve(1,1,0);
    	Print(1,1,0);
    	return 0;
    }
    

    Summary

    重点在了解括号dp的一般套路。

  • 相关阅读:
    字体下载大宝库:30款好看的免费英文字体
    jQuery Mapael – 呈现动态的矢量地图
    Qt:用 __thread 关键字让每个线程有自己的全局变量
    从C++到Qt(舍弃IDE或qmake、cmake等工具的束缚,尝试通过几个例子)
    C++11(及现代C++风格)和快速迭代式开发
    EventBus + Redis发布订阅模式
    并发、并行和高并发
    Span<T>和Memory<T>
    Lucene.Net做一个简单的搜索引擎-全文索引
    技术架构演变
  • 原文地址:https://www.cnblogs.com/BaseAI/p/12051489.html
Copyright © 2020-2023  润新知