POJ 1141 Brackets Sequence(구간 DP)
2263 단어 구간DP
이것은 아주 좋은 구간 DP문제로 하나의 서열에 물건을 삽입하는 것과 같은 문제는 모두 중간에서 두 개의 이 방향을 나누어 고려할 수 있다.
dp[i][j]는 i에서 j까지의 단락에 최소한 괄호를 삽입해야 하는 수량을 나타낸다. 분명히 이 수는min(dp[i][k], dp[k+1][j])와 같다. 그 중에서 0<=k
이 문제는 문자열을 복원하고 귀속적인 방법으로 print(a, b)이라는 함수로 a에서 b 구간의 상황을 출력하고 각 구간이 선택한 가장 좋은 구분점이 무엇인지, 그리고 가장 좌우 양쪽이 일치하도록 선택했는지 기록한다.그리고 출력을 되돌려줍니다. a==b일 때 s[a]가 (또는) 출력하고 반대로 출력합니다.
빈 줄 입력이 있는 경우scanf("%[^]s",str)로 입력하십시오
코드:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#include <string>
#include <map>
#define INF 1000000
int dp[105][105];
int path[105][105];
char s[105];
bool mat[105][105];
bool match(char a,char b){
return a=='['&&b==']'||a=='('&&b==')';
}
void print(int a,int b){
if(a>b) return ;
if(a==b){
if(s[a]=='('||s[a]==')') printf("()");
else printf("[]");
}
else if(mat[a][b]){
printf("%c",s[a]);
print(a+1,b-1);
printf("%c",s[b]);
}
else {
print(a,path[a][b]);
print(path[a][b]+1,b);
}
}
int main(){
scanf("%[^
]s",s);
int len=strlen(s);
if(len==0){
printf("
");
}
else{
for(int i=0;i<len;i++){
dp[i][i]=1;
}
for(int i=0;i<len-1;i++){
if(match(s[i],s[i+1])){
dp[i][i+1]=0;
mat[i][i+1]=1;
}
else{
dp[i][i+1]=2;
path[i][i+1]=i;
}
}
for(int i=3;i<=len;i++){
for(int j=0;j<len-i+1;j++){
dp[j][j+i-1]=INF;
int ist=0;
for(int k=j;k<j+i-1;k++){
if(dp[j][k]+dp[k+1][j+i-1]<dp[j][j+i-1]){
dp[j][j+i-1]=dp[j][k]+dp[k+1][j+i-1];
ist=k;
}
}
if(match(s[j],s[j+i-1])){
if(dp[j+1][j+i-2]<dp[j][j+i-1]){
mat[j][j+i-1]=1;
dp[j][j+i-1]=dp[j+1][j+i-2];
}
}
path[j][j+i-1]=ist;
}
}
print(0,len-1);
printf("
");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
POJ2955: Brackets(구간 DP)제목: 괄호 서열을 하나 드릴게요. 괄호는 두 가지(,)와 [,](), [], (), (), (), [], ()] [()] 이 괄호가 모두 일치하는 (,),(,(,)), ([(] 이런 것은 완전히 일치하지 않는 거예...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.