码迷,mamicode.com
首页 > 其他好文 > 详细

TOPCODER SAM 686 div1 300

时间:2016-05-27 23:36:02      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:

// TOPCODER SAM 686 div1 300

Problem Statement

带有小中括号的括号序列,问可以去掉多少子串,使得剩下的非空串是合法的。

Constraints

字符串长度不超过 40。

Examples

// ans[i] = count(s[i])
string s[] = {"()[]", "())", "()()", "([)]", "())[]][]([]()]]()]]]"};
int ans[] = {3, 2, 4, 2, 3854};

Solution

寻找反面,等价于有多少非空的子串是合法的。这是一个区间 dp,不难转移。

Code

  1. #include <string.h> 
  2.  
  3. #include <string> 
  4.  
  5. const int N = 123
  6.  
  7. class BracketSequenceDiv1 

  8. int n; 
  9. char str[N]; 
  10. long long dp[N][N]; 
  11.  
  12. public
  13. long long count(std::string std_str) 

  14. n = std_str.size(); 
  15. for (int i = 1; i <= n; ++i) { 
  16. str[i] = std_str[i-1]; 

  17. memset(dp, 0, sizeof(dp)); 
  18. return count(n); 

  19.  
  20. long long count(int n) 

  21. for (int d = 1; d <= n; ++d) { 
  22. for (int i = 1; i + d - 1 <= n; ++i) { 
  23. int j = i + d - 1
  24. dp[i][j] = dp[i][j-1]; 
  25. if (str[j] == ‘)‘) { 
  26. for (int k = i; k < j; ++k) { 
  27. // dp[i k-1] ( dp[k+1, j-1] ) 
  28. if (str[k] == ‘(‘) { 
  29. dp[i][j] += (dp[i][k-1] + 1) * (dp[k+1][j-1] + 1); 



  30. else if (str[j] == ‘]‘) { 
  31. for (int k = i; k < j; ++k) { 
  32. // dp[i, k-1] [ dp[k+1, j-1] ] 
  33. if (str[k] == ‘[‘) { 
  34. dp[i][j] += (dp[i][k-1] + 1) * (dp[k+1][j-1] + 1); 





  35. return dp[1][n]; 

  36. }; 

TOPCODER SAM 686 div1 300

标签:

原文地址:http://www.cnblogs.com/gu-castle/p/5536315.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!