博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOI 2005 瑰丽华尔兹(三维DP + 单调队列优化)
阅读量:4682 次
发布时间:2019-06-09

本文共 1853 字,大约阅读时间需要 6 分钟。

思路:

1. dp[k][x][y] 表示处理到第 k 个时间区间时,最终点落在 x, y 坐标上,移动的最大距离。

3. dp[k][x][y] = max(dp[k-1][x1][y1] + delta); 由于 delta 是相对偏移量,所以对于 x/y 所在的维度可以用单调队列优化。

4. 由于第 k - 1 次之后,无法确定第 k 步的起始位置,所以要采取枚举的办法,所以最终的时间复杂度为 O(N*M*K)

5. 初始状态为 dp[0][x][y] = 0, 其他赋值为 -INFS,这样才能保证枚举的过程中,最终结果是在以 (x, y) 为起始点出发的。

 

#include <iostream>
#include <cstdio>
#include <algorithm>
using
namespace
std;
 
const
int
MAXN = 210;
const
int
INFS = 0x3fffffff;
 
int
dx[5] = {-1, 1, 0, 0};
int
dy[5] = {0, 0, -1, 1};
 
char
grid[MAXN][MAXN];
int
t1, t2, dp[2][MAXN][MAXN], deq[MAXN], pos[MAXN];
 
void
solvedp(
int
x,
int
y,
int
width,
int
size,
int
d)
{
    
int
s = 0, e = -1;
    
for
(
int
i = 1; i <= width; ++i)
    
{
        
if
(grid[x][y] ==
'.'
)
        
{
            
int
val = dp[t1][x][y] - i;
            
while
(s <= e && deq[e] < val)
                
--e;
 
            
deq[++e] = val, pos[e] = i;
            
while
(i - pos[s] > size)
                
++s;
 
            
dp[t2][x][y] = deq[s] + i;
        
}
        
else
        
{
            
s = 0, e = -1;
            
dp[t2][x][y] = -INFS;
        
}
        
x += dx[d], y += dy[d];
    
}
}
 
int
main()
{
    
int
N, M, x, y, K;
    
while
(
scanf
(
"%d %d %d %d %d"
, &N, &M, &x, &y, &K) != EOF)
    
{
        
for
(
int
i = 1; i <= N; ++i)
            
scanf
(
"%s"
, &grid[i][1]);
 
        
for
(
int
i = 1; i <= N; ++i)
            
for
(
int
j = 1; j <= M; ++j)
                
dp[0][i][j] = -INFS;
        
dp[0][x][y] = 0;
 
        
t1 = 1, t2 = 0;
        
for
(
int
i = 0; i < K; ++i)
        
{
            
int
si, ti, di;
            
scanf
(
"%d %d %d"
, &si, &ti, &di);
 
            
t1 ^= 1, t2 ^= 1;
             
            
if
(di == 1)
            
{
                
for
(
int
j = 1; j <= M; ++j)
                    
solvedp(N, j, N, ti - si + 1, di - 1);
            
}
            
else
if
(di == 2)
            
{
                
for
(
int
j = 1; j <= M; ++j)
                    
solvedp(1, j, N, ti - si + 1, di - 1);
            
}
            
else
if
(di == 3)
            
{
                
for
(
int
j = 1; j <= N; ++j)
                    
solvedp(j, M, M, ti - si + 1, di - 1);
            
}
            
else
if
(di == 4)
            
{
                
for
(
int
j = 1; j <= N; ++j)
                    
solvedp(j, 1, M, ti - si + 1, di - 1);
            
}
        
}
 
        
int
ans = 0;
        
for
(
int
i = 1; i <= N; ++i)
            
for
(
int
j = 1; j <= M; ++j)
                
ans = max(ans, dp[t2][i][j]);
 
        
printf
(
"%d\n"
, ans);
    
}
    
return
0;
}

转载于:https://www.cnblogs.com/kedebug/archive/2013/02/28/2937861.html

你可能感兴趣的文章
设计模式系列 - 访问者模式
查看>>
20180507小测
查看>>
eclipse左侧不见
查看>>
python会缓存小的整数和短小的字符
查看>>
格网与四叉树索引
查看>>
多张照片拍摄、图片浏览
查看>>
html(5) css
查看>>
Azure Web连接到Azure MySql Db
查看>>
Linux shell 命令判断执行语法 ; , && , ||
查看>>
vim代码格式化插件clang-format
查看>>
RTP Payload Format for Transport of MPEG-4 Elementary Streams over http
查看>>
Aurora — 一个在 MSOffice 内输入 LaTeX 公式的很好用插件
查看>>
关于sql优化的一个小总结
查看>>
Java语言中的正则表达式
查看>>
Java环境变量设置
查看>>
【JBPM4】判断节点decision 方法3 handler
查看>>
filter 过滤器(监听)
查看>>
Linux进程间通信---共享内存
查看>>
Computer Information
查看>>
交换机/路由器上的 S口 F口 E口
查看>>