码迷,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. { 
  9. int n; 
  10. char str[N]; 
  11. long long dp[N][N]; 
  12.  
  13. public: 
  14. long long count(std::string std_str) 
  15. { 
  16. n = std_str.size(); 
  17. for (int i = 1; i <= n; ++i) { 
  18. str[i] = std_str[i-1]; 
  19. } 
  20. memset(dp, 0, sizeof(dp)); 
  21. return count(n); 
  22. } 
  23.  
  24. long long count(int n) 
  25. { 
  26. for (int d = 1; d <= n; ++d) { 
  27. for (int i = 1; i + d - 1 <= n; ++i) { 
  28. int j = i + d - 1; 
  29. dp[i][j] = dp[i][j-1]; 
  30. 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. } 
  36. } 
  37. } 
  38. else if (str[j] == ‘]‘) { 
  39. for (int k = i; k < j; ++k) { 
  40. // dp[i, k-1] [ dp[k+1, j-1] ] 
  41. if (str[k] == ‘[‘) { 
  42. dp[i][j] += (dp[i][k-1] + 1) * (dp[k+1][j-1] + 1); 
  43. } 
  44. } 
  45. } 
  46. } 
  47. } 
  48. return dp[1][n]; 
  49. } 
  50. }; 

TOPCODER SAM 686 div1 300

标签:

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

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