【noi2005试题】瑰丽华尔兹 单调队列优化DP
2014-03-31 22:03
459 查看
1A。。。。。。
dp【k】【i】【j】 表示第k段的倾斜之后到达(i,j)处时已经滑动的最长距离
根据倾斜的方向,来进行递推
比如 当向下倾斜时 dp【k】【i】【j】 = max( dp【k-1】【i-k】【j】 +k ) k <= t
这里如果不优化的时间复杂度就变成了 knmn
所以要用单调队列来优化这个决策的时间,优化前为o(n),优化后为o(1)
AC代码如下:
dp【k】【i】【j】 表示第k段的倾斜之后到达(i,j)处时已经滑动的最长距离
根据倾斜的方向,来进行递推
比如 当向下倾斜时 dp【k】【i】【j】 = max( dp【k-1】【i-k】【j】 +k ) k <= t
这里如果不优化的时间复杂度就变成了 knmn
所以要用单调队列来优化这个决策的时间,优化前为o(n),优化后为o(1)
AC代码如下:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; struct Node{ int a, b; int dir; }; int N, M, K; int sx, sy; char maps[210][210]; Node node[2000]; int dp[220][220][220]; void dp_up( int t, int step ){ int q[220], pos[220], head, tail; for( int j = 1; j <= M; j++ ){ head = 0; tail = -1; for( int i = N; i >= 1; i-- ){ if( maps[i][j] == 'x' ){ tail = head - 1; continue; }else{ if( dp[step-1][i][j] != -1 ){ while( head <= tail && dp[step-1][i][j] + i > q[tail] ) tail--; tail++; q[tail] = dp[step-1][i][j] + i; pos[tail] = i; } } while( head <= tail && pos[head] - i > t ) head++; if( head <= tail ) dp[step][i][j] = q[head] - i; } } } void dp_down( int t, int step ){ int q[220], pos[220], head, tail; for( int j = 1; j <= M; j++ ){ head = 0; tail = -1; for( int i = 1; i <= N; i++ ){ if( maps[i][j] == 'x' ){ tail = head - 1; continue; }else{ if( dp[step-1][i][j] != -1 ){ while( head <= tail && dp[step-1][i][j] - i > q[tail] ) tail--; tail++; q[tail] = dp[step-1][i][j] - i; pos[tail] = i; } } while( head <= tail && i - pos[head] > t ) head++; if( head <= tail ) dp[step][i][j] = q[head] + i; } } } void dp_left( int t, int step ){ int q[220], pos[220], head, tail; for( int i = 1; i <= N; i++ ){ head = 0; tail = -1; for( int j = M; j >= 1; j-- ){ if( maps[i][j] == 'x' ){ tail = head - 1; continue; }else{ if( dp[step-1][i][j] != -1 ){ while( head <= tail && dp[step-1][i][j] + j > q[tail] ) tail--; tail++; q[tail] = dp[step-1][i][j] + j; pos[tail] = j; } } while( head <= tail && pos[head] - j > t ) head++; if( head <= tail ) dp[step][i][j] = q[head] - j; } } } void dp_right( int t, int step ){ int q[220], pos[220], head, tail; for( int i = 1; i <= N; i++ ){ head = 0; tail = -1; for( int j = 1; j <= M; j++ ){ if( maps[i][j] == 'x' ){ tail = head - 1; continue; }else{ if( dp[step-1][i][j] != -1 ){ while( head <= tail && dp[step-1][i][j] - j > q[tail] ) tail--; tail++; q[tail] = dp[step-1][i][j] - j; pos[tail] = j; } } while( head <= tail && j - pos[head] > t ) head++; if( head <= tail ) dp[step][i][j] = q[head] + j; } } } int main(){ while( scanf( "%d%d%d%d%d", &N, &M, &sx, &sy, &K ) != EOF ){ for( int i = 1; i <= N; i++ ){ scanf( "%s", &maps[i][1] ); } for( int i = 1; i <= K; i++ ){ scanf( "%d%d%d", &node[i].a, &node[i].b, &node[i].dir ); } memset( dp, -1, sizeof( dp ) ); dp[0][sx][sy] = 0; for( int i = 1; i <= K; i++ ){ switch( node[i].dir ){ case 1 : dp_up( node[i].b - node[i].a + 1, i );break; case 2 : dp_down( node[i].b - node[i].a + 1, i );break; case 3 : dp_left( node[i].b - node[i].a + 1, i );break; case 4 : dp_right( node[i].b - node[i].a + 1, i );break; } } int ans = -1; for( int i = 1; i <= N; i++ ){ for( int j = 1; j <= M; j++ ){ ans = max( ans, dp[K][i][j] ); } } cout << ans << endl; } return 0; }
相关文章推荐
- [BZOJ1499][NOI2005]瑰丽华尔兹(单调队列优化DP)
- bzoj1499[NOI2005]瑰丽华尔兹 单调队列优化dp
- 【bzoj1499】[NOI2005]瑰丽华尔兹(dp+单调队列优化)
- bzoj1499 [NOI2005]瑰丽华尔兹 (单调队列优化DP)
- [BZOJ 1499][NOI 2005]瑰丽华尔兹(DP+单调队列优化)
- BZOJ1499 [NOI2005]瑰丽华尔兹 【单调队列优化dp】
- bzoj1499: [NOI2005]瑰丽华尔兹&&codevs1748 单调队列优化dp
- 【bzoj1499】[NOI2005]瑰丽华尔兹 【单调队列优化dp】
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
- Bzoj - 1499 [Noi2005] 瑰丽华尔兹 [DP][单调队列优化]
- 【NOI2005T1】瑰丽华尔兹-DP单调队列优化
- 【DP】【单调队列】【NOI2005】瑰丽华尔兹
- 【DP】【单调队列】【NOI2005】瑰丽华尔兹
- [NOI2005]瑰丽华尔兹 && dp单调队列
- NOI 2005 瑰丽华尔兹(三维DP + 单调队列优化)
- bzoj1499 [NOI2005]瑰丽华尔兹(luoguP2254)(dp+单调队列)
- bzoj 1499: [NOI2005]瑰丽华尔兹【dp+单调队列】
- [NOI 2005] 瑰丽华尔兹:dp+单调队列
- [DP 暴力 || ST表 || 单调队列] BZOJ 1499 [NOI2005]瑰丽华尔兹
- NOI 2005 瑰丽华尔兹(DP+单调队列)