zoukankan      html  css  js  c++  java
  • codeforces 1272F dp+记录路径

    题意

    给出两个括号序列 (S)(T),让你构造一个最短的合法括号序列使 (S)(T) 是它的子序列。

    分析

    (dp[i][j][k]) 为这个最短的合法括号序列的前缀包含 (S) 的前 (i) 个字符,T的前 (j) 个字符且左括号的数量大于右括号的数量为 (k)时的长度。

    • 如果我们要添加一个左括号

      (dp[nexi][nexj][k+1]=min(dp[i][j][k]+1,dp[nexi][nexj][k+1]))

      (nexi) 为添加一个左括号后能匹配到的下一个 (i)(nexj) 为添加一个左括号能匹配到的下一个 (j)

    • 如果我们要添加一个右括号

      (dp[nexi][nexj][k-1]=min(dp[i][j][k]+1,dp[nexi][nexj][k-1]))

      (nexi) 为添加一个右括号后能匹配到的下一个 (i)(nexj) 为添加一个右括号能匹配到的下一个 (j)

    (dp) 过程中用一个数组记录下转移的前驱就可以倒推还原这个括号序列。

    Code

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define lson l,mid,p<<1
    #define rson mid+1,r,p<<1|1
    #define pb push_back
    #define ll long long
    using namespace std;
    const int inf=1e9;
    const int mod=1e9+7;
    const int maxn=2e2+10;
    char s[maxn],t[maxn];
    int n,m;
    int dp[maxn][maxn][2*maxn];
    struct ppo{
    	int x,y,k;
    	char c;
    }pre[maxn][maxn][2*maxn];
    int main(){
    	//ios::sync_with_stdio(false);
    	//freopen("in","r",stdin);
    	scanf("%s%s",s,t);
    	n=strlen(s);m=strlen(t);
    	for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) for(int k=0;k<2*maxn;k++) dp[i][j][k]=inf;
    	dp[0][0][0]=0;
    	for(int i=0;i<=n;i++){
    		for(int j=0;j<=m;j++){
    			for(int k=0;k<2*maxn;k++){
    				if(dp[i][j][k]==inf) continue;
    				int x=i+(i<n&&s[i]=='(');
    				int y=j+(j<m&&t[j]=='(');
    				if(k+1<2*maxn&&dp[i][j][k]+1<dp[x][y][k+1]){
    					dp[x][y][k+1]=dp[i][j][k]+1;
    					pre[x][y][k+1]=ppo{i,j,k,'('};
    				}
    				x=i+(i<n&&s[i]==')');
    				y=j+(j<m&&t[j]==')');
    				if(k>0&&dp[i][j][k]+1<dp[x][y][k-1]){
    					dp[x][y][k-1]=dp[i][j][k]+1;
    					pre[x][y][k-1]=ppo{i,j,k,')'};
    				}
    			}
    		}
    	}
    	string str;
    	int x=n,y=m,k=0,p=0;
        for(int i=0;i<2*maxn;i++){
            if(dp[n][m][p]+p>dp[n][m][i]+i) p=i;
        }
        for(int i=0;i<p;i++) str.pb(')');
        k=p;
    	for(int i=0;i<dp[n][m][p];i++){
    		ppo p=pre[x][y][k];
    		str.pb(p.c);
    		x=p.x;y=p.y;k=p.k;
    	}
    	reverse(str.begin(), str.end());
    	cout<<str<<endl;
    	return 0;
    }
    
  • 相关阅读:
    python核心编程2 第八章 练习
    python核心编程2 第六章 练习
    python核心编程2 第五章 练习
    Redis
    CENTOS7错误:Cannot find a valid baseurl for repo: base/7/x86_6
    HTTP协议
    计算机网络知识点
    好记性不如烂笔头~
    一些算法题
    解决mysql插入数据时出现Incorrect string value: 'xF0x9F...' 的异常
  • 原文地址:https://www.cnblogs.com/xyq0220/p/12061335.html
Copyright © 2011-2022 走看看