poj 2955 Brackets 区间DP
题目链接:http://poj.org/problem?id=2955
不容易啊,终于把这道题A了,还是对区间DP不熟悉啊。。
思路:
关键就是怎样进行状态转移;
我的想法是定义dp[i][j]表示从i到j的最优匹配数,那么对于k(i<=k<=j)
如果s[i]和s[k]匹配,那么dp[i][j]=max(dp[i+1][k-1]+dp[k+1][j]+2,dp[i][j]);
否则,dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
其实就是对于区间i到j 不断进行划分,取最优啊
代码:
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 #include<string> 6 using namespace std; 7 int dp[110][110]; 8 string s; 9 bool match(int i,int j) 10 { 11 if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']')) 12 return true; 13 return false; 14 } 15 int main() 16 { 17 18 while(cin>>s) 19 { 20 int ans=-1; 21 if(s=="end") break; 22 memset(dp,0,sizeof(dp)); 23 int n=s.length(); 24 for(int j=1;j<n;j++) 25 for(int i=j-1;i>=0;i--){ 26 for(int k=i;k<=j;k++){ 27 if(match(i,k)) 28 dp[i][j]=max(dp[i+1][k-1]+dp[k+1][j]+2,dp[i][j]); 29 else dp[i][j]=max(dp[i][k]+dp[k+1][j],dp[i][j]); 30 } 31 } 32 cout<<dp[0][n-1]<<endl; 33 } 34 return 0; 35 }