UVa 11920 - 0 s, 1 s and ? Marks (二分 + DP)

来源:互联网 发布:js数据添加二维数组 编辑:程序博客网 时间:2024/05/18 13:10

题意

?可以填0或者1,问一个序列中的最短连续相同序列的长度是多少。

思路

二分 + 检查。

一开始想不到怎么检查是否合法,看了yiwei的题解。

dp[i][0]表示第i个位置填0的长度,dp[i][1]表示第i个位置填1的长度。

如果某个位置是1,如果前面的位置是0,dp[i][1] = 1,否则如果前面位置1是合法的,dp[i][1] = dp[i - 1][1] + 1。 
0以此类推

如果是?,就是上面两种情况合起来。

这题TLE得醉了。按理来说O(nlogn)不可能TLE,但就是TLE了。 
后来找了N久的原因是检查的时候我没有用len表示长度,每次都strlen()。 
这样5000组数据 * 1000长度 * 10检查次数,已经差不多爆了。

代码

  1. #include <cstdio>
  2. #include <stack>
  3. #include <list>
  4. #include <set>
  5. #include <iostream>
  6. #include <string>
  7. #include <vector>
  8. #include <queue>
  9. #include <functional>
  10. #include <cstring>
  11. #include <iomanip>
  12. #include <algorithm>
  13. #include <cctype>
  14. #include <string>
  15. #include <map>
  16. #include <cmath>
  17. using namespace std;
  18. #define LL long long
  19. #define ULL unsigned long long
  20. #define SZ(x) (int)x.size()
  21. #define Lowbit(x) ((x) & (-x))
  22. #define MP(a, b) make_pair(a, b)
  23. #define MS(arr, num) memset(arr, num, sizeof(arr))
  24. #define PB push_back
  25. #define X first
  26. #define Y second
  27. #define ROP freopen("input.txt", "r", stdin);
  28. #define MID(a, b) (a + ((b - a) >> 1))
  29. #define LC rt << 1, l, mid
  30. #define RC rt << 1|1, mid + 1, r
  31. #define LRT rt << 1
  32. #define RRT rt << 1|1
  33. #define BitCount(x) __builtin_popcount(x)
  34. #define BitCountll(x) __builtin_popcountll(x)
  35. #define LeftPos(x) 32 - __builtin_clz(x) - 1
  36. #define LeftPosll(x) 64 - __builtin_clzll(x) - 1
  37. const double PI = acos(-1.0);
  38. const int INF = 0x3f3f3f3f;
  39. const double eps = 1e-8;
  40. const int MAXN = 1000 + 10;
  41. const int MOD = 1000007;
  42. const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
  43. int cases = 0;
  44. typedef pair<int, int> pii;
  45. typedef vector<int>::iterator viti;
  46. typedef vector<pii>::iterator vitii;
  47. int dp[MAXN][3], len;
  48. char str[MAXN];
  49. bool Check(int limit)
  50. {
  51. for (int i = 1; i <= len; i++)
  52. {
  53. dp[i][0] = dp[i][1] = -1;
  54. if (str[i] == '0')
  55. {
  56. if (dp[i - 1][1] >= 0) dp[i][0] = 1;
  57. else if (dp[i - 1][0] >= 0 && dp[i - 1][0] + 1 <= limit) dp[i][0] = dp[i - 1][0] + 1;
  58. }
  59. else if (str[i] == '1')
  60. {
  61. if (dp[i - 1][0] != -1) dp[i][1] = 1;
  62. else if (dp[i - 1][1]!= -1 && dp[i - 1][1] + 1 <= limit) dp[i][1] = dp[i - 1][1] + 1;
  63. }
  64. else
  65. {
  66. if (dp[i - 1][0] != -1) dp[i][1] = 1;
  67. else if (dp[i - 1][1] != -1 && dp[i - 1][1] + 1 <= limit) dp[i][1] = dp[i - 1][1] + 1;
  68. if (dp[i - 1][1] != -1) dp[i][0] = 1;
  69. else if (dp[i - 1][0] != -1 && dp[i - 1][0] + 1 <= limit) dp[i][0] = dp[i - 1][0] + 1;
  70. }
  71. if (dp[i][0] == -1 && dp[i][1] == -1) return false;
  72. }
  73. return true;
  74. }
  75. int Solve()
  76. {
  77. int l = 1, r = len, mid;
  78. while (l <= r)
  79. {
  80. mid = MID(l, r);
  81. if (Check(mid)) r = mid - 1;
  82. else l = mid + 1;
  83. }
  84. return l;
  85. }
  86. int main()
  87. {
  88. //ROP;
  89. int T, i, j;
  90. scanf("%d", &T);
  91. while (T--)
  92. {
  93. scanf("%s", str + 1);
  94. len = strlen(str + 1);
  95. printf("Case %d: %d\n", ++cases, Solve());
  96. }
  97. return 0;
  98. }
0 0