POJ-3276(异或DP)
2014-07-16 10:40
148 查看
暴力方法的复杂度会是O(N^3),而题目给定的N的范围是小于等于5000,暴力法必然会超时,考虑每一个位置的翻转情况,我们可以看到,其和前一个位置的翻转情况有密切联系:
由上面的状态方程我们可以看到pre[i]仅与pre[i-1]、post[i-k]、post[i-1]有关,我们完全可以省去pre[]数组而用一个滚动的变量来表示pre[i]:
pre[i] = post[i-k+1] ^ post[i-k+2] ^ ... ^ post[i-1] post[i] = s[i] ^ pre[i] ==================================================== we have: pre[i-1] = post[i-k] ^ post[i-k+1] ^ ... ^ post[i-2] thus: pre[i] = pre[i-1] ^ post[i-k] ^ post[i-1]
#include <stdio.h> int N, K, M; char s[5000] = {0};/* initial state, 'F' <=> 0, 'B' <=> 1 */ char pre[5000] = {0};/* whether i should be flipped by flips in front */ char post[5000] = {0};/* post[i] <=> whether to start a flip at i */ int main() { int i, k, m; char c; while(scanf("%d", &N) == 1){ K = 1; M = 0; for(i = 0; i < N; ++i){ scanf(" %c", &c); if(s[i] = c != 'F') ++M; } for(k = 2; k <= N; ++k){ pre[0] = 0; if(post[0] = s[0]) m = 1; else m = 0; for(i = 1; i + k <= N; ++i){ if(i >= k) pre[i] = pre[i-1] ^ post[i-k] ^ post[i-1]; else pre[i] = pre[i-1] ^ post[i-1]; if(post[i] = s[i] ^ pre[i]) ++m; } for(; i < N; ++i){ if(i >= k) pre[i] = pre[i-1] ^ post[i-k] ^ post[i-1]; else pre[i] = pre[i-1] ^ post[i-1]; if(pre[i] ^ s[i]) break; post[i] = 0; } if(i == N && m < M) K = k, M = m; } printf("%d %d\n", K, M); } return 0; }
由上面的状态方程我们可以看到pre[i]仅与pre[i-1]、post[i-k]、post[i-1]有关,我们完全可以省去pre[]数组而用一个滚动的变量来表示pre[i]:
#include <stdio.h> int N, K, M; char s[5000] = {0};/* initial state, 'F' <=> 0, 'B' <=> 1 */ char post[5000] = {0};/* post[i] <=> whether to start a flip at i */ int main() { int i, k, m; char c, pre; while(scanf("%d", &N) == 1){ K = 1; M = 0; for(i = 0; i < N; ++i){ scanf(" %c", &c); if(s[i] = c != 'F') ++M; } for(k = 2; k <= N; ++k){ pre = 0; if(post[0] = s[0]) m = 1; else m = 0; for(i = 1; i + k <= N; ++i){ if(i >= k) pre ^= post[i-k] ^ post[i-1]; else pre ^= post[i-1]; if(post[i] = s[i] ^ pre) ++m; } for(; i < N; ++i){ if(i >= k) pre ^= post[i-k] ^ post[i-1]; else pre ^= post[i-1]; if(s[i] ^ pre) break; post[i] = 0; } if(i == N && m < M) K = k, M = m; } printf("%d %d\n", K, M); } return 0; }
相关文章推荐
- POJ 3276 dp
- poj 3342 Party at Hali-Bula(树形dp)
- poj 1185 && NYOJ 85 炮兵阵地(状态压缩dp)
- Brackets(POJ - 2955)区间dp
- POJ 1185 炮兵阵地(状压DP入门)
- poj 1185 炮兵阵地(DP-状态DP)
- POJ 2342 Anniversary Party ( 树形DP )
- poj 2229 Sumsets(dp 或 数学)
- POJ 3186 Treats for the Cows(区间dp)
- poj 3728(LCA + dp)
- POJ 3286 How many 0's? (数位dp)
- poj Function Run Fun(DP)(记忆化搜索)
- POJ 1260 简单dp问题 Pearls
- POJ 3280 Cheapest Palindrome【DP之经典回文问题】
- POJ 3176 Cow Bowling (简单DP)
- POJ 3670 && POJ 3671 (dp)
- POJ Corn Fields(状态压缩DP)
- POJ 2441 Arrange the Bulls 状态压缩DP
- POJ-3254-Corn Fields(状压DP)
- POJ 2506 Tiling(DP+大数运算)