您的位置:首页 > 产品设计 > UI/UE

ural1183&&poj1141 Brackets Sequence(区间DP+记录路径)

2017-07-29 11:47 267 查看
黑书动规1.5.1例题1,原题多了记录路径,要递归打印出来。

dp[i][j]表示s[i…j]需加至少多少个括号才能变成合法的。

状态转移:dp[i][j]=min(dp[i][k]+dp[k+1][j])(i≤k<j)

如果s[i]和s[j]匹配了,如果i+1==j,dp[i][j]=0;

else 在dp[i+1][j-1]与dp[i][j]中取最小。

op[i][j]记录操作,0–加入另一半括号; 正数k–从k分开; -1–已匹配

循环i要从大到小,j要从小到大,因为计算dp[i][j]时会用到dp[i+k][j]和dp[i][j-k]。

#include <cstdio>
#include <cstring>
#define inf 2000000000
int const N=110;
int dp

,op

;
char s
;
void print(int i,int j){
if(i>j) return;//注意判错
if(op[i][j]>0){
print(i,op[i][j]);
print(op[i][j]+1,j);return;
}
if(!op[i][j]){
if(s[i]=='('||s[i]==')') printf("()");
else printf("[]");return;
}
printf("%c",s[i]);
print(i+1,j-1);
printf("%c",s[j]);return;
}
int main(){
//  freopen("a.in","r",stdin);
scanf("%s",s+1);
int n=strlen(s+1);
for(int i=n;i>=1;--i)
for(int j=i;j<=n;++j){
if(i==j){
dp[i][j]=1;op[i][j]=0;
continue;//0-add the one that maches
}
int temp=i,ans=inf;
for(int k=i;k<j;++k)
if(dp[i][k]+dp[k+1][j]<ans)
ans=dp[i][k]+dp[k+1][j],temp=k;
dp[i][j]=ans;op[i][j]=temp;//positive value--split at op[i][j]
if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']'){
if(i+1==j) dp[i][j]=0,op[i][j]=-1;//-1--mached
else if(dp[i+1][j-1]<dp[i][j]) dp[i][j]=dp[i+1][j-1],op[i][j]=-1;
}
}
print(1,n);printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: