[NOI2005]瑰丽华尔兹 && dp单调队列
2014-12-06 16:40
525 查看
裸DP (知道要用单调队列的前提下)按照时间区间做DP 单调队列也没什么特别的 就是手写双端队列要注意清0 以及各种数组加减号有点容易打错略坑
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define MAXN 200 char Map[MAXN+10][MAXN+10]; int dp[MAXN+10][MAXN+10][MAXN+10]; int n, m, K; struct node{ int st, ed, dir; }A[MAXN+10]; int Q[MAXN*10+10]; int F, R; int main() { int stx, sty; scanf("%d%d%d%d%d", &n, &m, &stx, &sty, &K); for(int i = 1; i <= n; i++) scanf("%s", Map[i]+1); memset(dp, ~0x3f, sizeof(dp)); dp[0][stx][sty] = 0; for(int i = 1; i <= K; i++) scanf("%d%d%d", &A[i].st, &A[i].ed, &A[i].dir); for(int d = 1; d <= K; d++) { int T = A[d].ed - A[d].st + 1, dir = A[d].dir; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) dp[d][i][j] = dp[d-1][i][j]; if(dir == 1) for(int j = 1; j <= m; j++) { F = R = Q[0] = 0; memset(Q, 0, sizeof(Q)); for(int i = n; i >= 1; i--) { if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; } while(F < R && Q[F] - i > T) F++; dp[d][i][j] = max(dp[d][i][j], dp[d-1][Q[F]][j] + Q[F] - i); while(F < R && dp[d-1][i][j] + i >= dp[d-1][Q[R-1]][j] + Q[R-1]) R--; Q[R++] = i; } } if(dir == 2) for(int j = 1; j <= m; j++) { F = R = Q[0] = 0; memset(Q, 0, sizeof(Q)); for(int i = 1; i <= n; i++) { if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; } while(F < R && i - Q[F] > T) F++; dp[d][i][j] = max(dp[d][i][j], dp[d-1][Q[F]][j] + i - Q[F]); while(F < R && dp[d-1][i][j] - i >= dp[d-1][Q[R-1]][j] - Q[R-1]) R--; Q[R++] = i; } } if(dir == 3) for(int i = 1; i <= n; i++) { F = R = Q[0] = 0; memset(Q, 0, sizeof(Q)); for(int j = m; j >= 1; j--) { if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; } while(F < R && Q[F] - j > T) F++; dp[d][i][j] = max(dp[d][i][j], dp[d-1][i][Q[F]] + Q[F] - j); while(F < R && dp[d-1][i][j] + j >= dp[d-1][i][Q[R-1]] + Q[R-1]) R--; Q[R++] = j; } } if(dir == 4) for(int i = 1; i <= n; i++) { F = R = Q[0] = 0; for(int j = 1; j <= m; j++) { if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; } while(F < R && j - Q[F] > T) F++; dp[d][i][j] = max(dp[d][i][j], dp[d-1][i][Q[F]] - Q[F] + j); while(F < R && dp[d-1][i][j] - j >= dp[d-1][i][Q[R-1]] - Q[R-1]) R--; Q[R++] = j; } } } int Ans = -1; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) Ans = max(Ans, dp[K][i][j]); printf("%d", Ans); }
相关文章推荐
- bzoj1499: [NOI2005]瑰丽华尔兹&&codevs1748 单调队列优化dp
- zstu3924 [NOI2005]瑰丽华尔兹 (单调队列dp)
- Bzoj - 1499 [Noi2005] 瑰丽华尔兹 [DP][单调队列优化]
- 【noi2005试题】瑰丽华尔兹 单调队列优化DP
- [BZOJ1499][NOI2005]瑰丽华尔兹 dp+单调队列
- 【DP】【单调队列】【NOI2005】瑰丽华尔兹
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
- NOI 2005 瑰丽华尔兹(DP+单调队列)
- bzoj 1499: [NOI2005]瑰丽华尔兹【dp+单调队列】
- 【BZOJ1499】[NOI2005]瑰丽华尔兹 单调队列+DP
- bzoj1499[NOI2005]瑰丽华尔兹 单调队列优化dp
- BZOJ1499 [NOI2005]瑰丽华尔兹 【单调队列优化dp】
- bzoj1499 [NOI2005]瑰丽华尔兹 (单调队列优化DP)
- 【DP】【单调队列】【NOI2005】瑰丽华尔兹
- 【bzoj1499】[NOI2005]瑰丽华尔兹(dp+单调队列优化)
- [DP 暴力 || ST表 || 单调队列] BZOJ 1499 [NOI2005]瑰丽华尔兹
- [BZOJ1499][NOI2005]瑰丽华尔兹(单调队列优化DP)
- 【bzoj1499】[NOI2005]瑰丽华尔兹 【单调队列优化dp】
- [NOI 2005] 瑰丽华尔兹:dp+单调队列
- [BZOJ 1499][NOI 2005]瑰丽华尔兹(DP+单调队列优化)