当前位置: 代码迷 >> 综合 >> UVA 1626 Brackets sequence
  详细解决方案

UVA 1626 Brackets sequence

热度:44   发布时间:2023-09-23 09:13:06.0

状态表示:d(i,j) 表示 i~j至少要添加几个括号

状态转移:1)(S) 或 [S] 转移成 S ,即d(i,j) --> d(i+1,j-1) 如果 s[i]==s[j]     

                 2) A=S1+S2 转移成 S1和S2  ,即 d(i,j0 --> d(i,k)+d(k+1,j) 

但每种都要转移到第二种方法试一试 ,如[][]只是第一种会导致到 ][ 状态去了

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm> 
#include<cmath>
#include<vector>
using namespace std;
const int maxn=100+5;
int d[maxn][maxn],N;
char s[maxn]; 
//d(i,j) 表示i~j 要添加的括号数 
bool match(char a,char b){ return (a=='['&&b==']')||(a=='('&&b==')'); }
void dp()
{for(int i=0;i<N;i++)d[i+1][i]=0,d[i][i]=1;    //只有一个字符只要补上另一个就好 for(int i=N-2;i>=0;i--)for(int j=i+1;j<N;j++){d[i][j]=N;if(match(s[i],s[j]))      //第一种状态转移 d[i][j]=min(d[i][j],d[i+1][j-1]);for(int k=i;k<j;k++)      //第二种状态转移 d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);}}
void print_ans(int i,int j)
{if(i>j) return;   if(i==j)          //就一个字符的话直接补上 {if(s[i]=='('||s[i]==')') printf("()");else printf("[]");return ;}int ans=d[i][j];if(match(s[i],s[j])&&ans==d[i+1][j-1]){    //第一种状态转移printf("%c",s[i]);print_ans(i+1,j-1);printf("%c",s[j]);return ;}for(int k=i;k<j;k++)if(ans==d[i][k]+d[k+1][j]){                //第二种状态转移print_ans(i,k);print_ans(k+1,j);return ;}}
int main()
{int n;fgets(s,maxn,stdin);sscanf(s,"%d",&n);fgets(s,maxn,stdin);while(n--){fgets(s,maxn,stdin);memset(d,-1,sizeof(d));   N=strlen(s)-1;dp();print_ans(0,N-1);cout<<endl;if(n) cout<<endl;fgets(s,maxn,stdin);}return 0;
}


  相关解决方案