题目链接:
https://vjudge.net/problem/UVA-1626
题意:
题解:
dp[i][j]:= i~j需要最少的括号
区间dp:
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
if(match(s[i],s[j])) dp[i][j] = min(dp[i][j],dp[i+1][j-1]);
学到了一种dp打印解得方式
读入真坑啊…
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MS(a) memset(a,0,sizeof(a))
#define MP make_pair
#define PB push_back
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll 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*10+ch-'0';ch=getchar();}
return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e5+10;
char s[maxn];
int dp[105][105];
bool match(char s1,char s2){
if((s1=='(' && s2==')') || (s1=='['&&s2==']')) return true;
return false;
}
void print(int i,int j){
if(i > j) return ;
if(i == j){
if(s[i]=='(' || s[i]==')') printf("()");
else printf("[]");
return ;
}
int ans = dp[i][j];
if(match(s[i],s[j]) && ans==dp[i+1][j-1]) {
printf("%c",s[i]); print(i+1,j-1); printf("%c",s[j]);
return ;
}
for(int k=i; k<j; k++){
if(ans == dp[i][k]+dp[k+1][j]){
print(i,k); print(k+1,j);
return ;
}
}
}
int main(){
int T;
gets(s);
sscanf(s,"%d",&T);
gets(s);
while(T--){
gets(s);
int n = strlen(s);
for(int i=0; i<n; i++){
dp[i+1][i] = 0;
dp[i][i] = 1;
}
for(int len=1; len<n; len++){
for(int i=0; i+len<n; i++){
int j = i+len;
dp[i][j] = n;
if(match(s[i],s[j])) dp[i][j] = min(dp[i][j],dp[i+1][j-1]);
for(int k=i; k<j; k++){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
}
print(0,n-1);
puts("");
if(T) puts("");
gets(s);
}
return 0;
}