括號匹配
阿新 • • 發佈:2018-06-27
include scanf namespace while 技術 char pri return 需要
poj 2955
http://poj.org/problem?id=2955
題目大意:找到數量最多的完全匹配的括號 ‘[’與‘]‘匹配,‘(‘與‘)‘匹配
區間dp
定義dp[i][j]為從i到j數量最多的完全匹配的括號
當 str[i]==‘[‘ && str[j]==‘]‘ 或 str[i]==‘(‘ && str[j]==‘)‘ 時 dp[i][j]=dp[i+1][j-1]+2;
代碼
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int N=110; char str[N]; int dp[N][N]; int main() { while(~scanf("%s",str+1)) { if(str[1]==‘e‘) break; memset(dp,0,sizeof(dp)); int ans=-1; int len=strlen(str+1); for(int v=1;v<=len;v++) for(int i=1;i+v-1<=len;i++) { int j=i+v-1; if((str[i]==‘[‘&&str[j]==‘]‘)||(str[i]==‘(‘&&str[j]==‘)‘)) dp[i][j]=dp[i+1][j-1]+2; for(int k=i;k<j;k++) dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]); ans=max(ans,dp[i][j]); } printf("%d\n",ans); } return 0; }
變式:括號匹配2
只需要括號總數減去最大完全匹配括號數即可
代碼
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int N=110; char str[N]; int dp[N][N]; int main() { int t; scanf("%d",&t); while(t--) { scanf("%s",str+1); memset(dp,0,sizeof(dp)); int ans=-1; int len=strlen(str+1); for(int v=1;v<=len;v++) for(int i=1;i+v-1<=len;i++) { int j=i+v-1; if((str[i]==‘[‘&&str[j]==‘]‘)||(str[i]==‘(‘&&str[j]==‘)‘)) dp[i][j]=dp[i+1][j-1]+2; for(int k=i;k<j;k++) dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]); ans=max(ans,dp[i][j]); } printf("%d\n",len-ans); } return 0; }
括號匹配