cf1272F-- classic rose-dimensional dp, good question!

/ * 
To the two brackets sequences, strings with a legitimate bracket to cover the two strings, determine the shortest string 
problem can be decomposed into two conditions: 
    1. a shortest sequence bracketed to cover the two strings 
    2 this sequence to be legally 
considered first the first condition: 
    difficult to think of two state dp [i, j] expressed match s [1..i], t shortest length [1..j] when 
     the transfer is very simple: the initial state dp [0,0] = 0, the back plus '(', behind the increase ''): all were taken to update status corresponding to   
    the final result is dp [lens, lent] 

and then again consider the condition on the second 
    bracket sequence lawful provided that all the prefixes and> = 0, and the final and is 0 (know what I mean) 
    to make the last train to meet this condition, we must take into account the prefix and the state at the time of the transfer, the state> = 0 , 
    naturally think of a dimension l dp, dp [i, j, k] indicates a match to be s [1..i], t [1..j ] and the shortest prefix length k and 
    the initial state dp [0,0 , 0] = 0, the transfer supra 
    this prefix and range must in [0, lens + lent], so the complexity of the whole dp is O (n ^ 3) 
the final answer: 
    dp [I, J, K] + K where to find the smallest recorded as min k 
due to output solution, so we can write down the precursor (this is the minutiae achieved) 
* / 
#include <bits / STDC ++. H>
 a using  namespace std;
#define N 1005

char s[N],t[N];
int dp[205][205][405],lens,lent; 
struct Node{
    int i,j,k,flag,len;
    Node(){}
    Node(int i,int j,int k,int flag,int len):i(i),j(j),k(k),flag(flag),len(len){}
}pre[205][205][405];

stack<char>stk;
void print(Node node){
    if(node.flag==-1)stk.push(')');
    else if(node.flag==1)stk.push('(');
    if(node.len)
        print(pre[node.i][node.j][node.k]);
}

int main(){
    scanf("%s%s",s+1,t+1);
    lens=strlen(s+1);lent=strlen(t+1);
    
    memset(dp,0x3f,sizeof dp);
    dp[0][0][0]=0;
    
    for(int i=0;i<=lens;i++)
        for(int j=0;j<=lent;j++)
            for(int k=0;k<=lens+lent;k++){
                if(dp[i][j][k]==0x3f3f3f3f)continue;
                if(k){//加个右括号 
                    int f1,f2;
                    if(s[i+1]==')')f1=1;
                    else f1=0;
                    if(t[j+1]==')')f2=1;
                    else f2=0;
                    if(dp[i][j][k]+1<dp[i+f1][j+f2][k-1]){//更新状态 
                        Node node=Node(i,j,k,-1,dp[i][j][k]);
                        pre[i+f1][j+f2][k-1]=node;
                        dp[i+f1][j+f2][k-1]=dp[i][j][k]+1 ;                  
                    } 
                } 
                // add a left bracket 
                int F1, F2;
                 IF (S [I + 1 ] == ' ( ' ) F1 = 1 ;
                 the else F1 = 0 ;
                 IF (T [J + 1 ] == ' ( ' ) = F2 . 1 ;
                 the else F2 = 0 ;
                 IF (DP [I] [J] [K] + . 1 <DP [I + F1] [F2 + J] [K + . 1 ]) { // update state
                    Node node=Node(i,j,k,1,dp[i][j][k]);
                    pre[i+f1][j+f2][k+1]=node;
                    dp[i+f1][j+f2][k+1]=dp[i][j][k]+1;                 
                } 
            }
    
    int Min=0x3f3f3f3f,mink=0;
    for(int k=1;k<=lens+lent;k++){
        if(dp[lens][lent][k]+k<dp[lens][lent][mink]+mink){
            mink=k;
        }
    } 
    
    for(int i=1;i<=mink;i++)stk.push(')');    
    print(pre[lens][lent][mink]);
    while(stk.size()){
        cout<<stk.top();
        stk.pop();
    }
    puts("");
}

Guess you like

Origin www.cnblogs.com/zsben991126/p/12113735.html