话说这题自己折腾好久还是没有推出转移的公式来啊------------------
只想出了dp[i][j]表示i到j的最大括号匹配的数目--ค(TㅅT)-------------------
后来搜题解看到有两种有一点点不同的做法
dp[i][j] = max(dp[i+1][j-1] + ok(i,j), dp[i][k] + dp[k+1][j])
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int d[505][505]; 8 char s[505]; 9 int n; 10 11 int ok(int x,int y){ 12 if(s[x] == '(' && s[y] == ')') return 1; 13 if(s[x] == '[' && s[y] == ']') return 1; 14 return 0; 15 } 16 17 int dp(int x,int y){ 18 int& ans = d[x][y]; 19 if(ans >= 0) return ans; 20 if(x > y) return 0; 21 22 ans = dp(x+1,y-1) + ok(x,y); 23 for(int k = x;k < y;k++){ 24 ans = max(ans,dp(x,k) + dp(k+1,y)); 25 // printf("ans = %d ",ans); 26 } 27 return ans; 28 } 29 30 int main(){ 31 while(scanf("%s",s+1) != EOF){ 32 if(s[1] == 'e') break; 33 n = strlen(s+1); 34 35 memset(d,-1,sizeof(d)); 36 37 int res = dp(1,n); 38 39 // for(int i = 1;i <= n;i++) 40 // for(int j = 1;j <= n;j++) 41 // printf("d[%d][%d] = %d ",i,j,d[i][j]); 42 43 printf("%d ",2*res); 44 } 45 return 0; 46 }
另一种是考虑i的作用,感觉和换衣服那题有点点像
如果i只被第i个位置用,不考虑后来和它配对的,dp[i][j] = dp[i+1][j]
考虑i和后面的配对,dp[i][j] = max(dp[i][j],dp[i+1][k-1] + dp[k+1][j] + ok(i,k) );
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int d[505][505]; 8 char s[505]; 9 int n; 10 11 int ok(int x,int y){ 12 if(s[x] == '(' && s[y] == ')') return 2; 13 if(s[x] == '[' && s[y] == ']') return 2; 14 return 0; 15 } 16 17 int dp(int x,int y){ 18 int& ans = d[x][y]; 19 if(ans >= 0) return ans; 20 if(x >= y) { 21 ans = 0; 22 return ans; 23 } 24 if(y == x+1) { 25 ans = ok(x,y); 26 return ans; 27 } 28 29 ans = dp(x+1,y); 30 for(int k = x;k <= y;k++){ 31 if(ok(x,k)) ans = max(ans,dp(x+1,k-1) + dp(k+1,y) + 2); 32 // printf("ans = %d ",ans); 33 } 34 return ans; 35 } 36 37 int main(){ 38 while(scanf("%s",s+1) != EOF){ 39 if(s[1] == 'e') break; 40 n = strlen(s+1); 41 42 memset(d,-1,sizeof(d)); 43 44 int res = dp(1,n); 45 46 //for(int i = 1;i <= n;i++) 47 //for(int j = 1;j <= n;j++) 48 // printf("d[%d][%d] = %d ",i,j,d[i][j]); 49 50 printf("%d ",res); 51 } 52 return 0; 53 }