3111: [Zjoi2013]蚂蚁寻路 - BZOJ
2014-03-06 17:01
218 查看
题目描述 Description
在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点
处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯
前走了多长。蚂蚁转弯是有一定特点的,即它的转弯序列一定是如下的形式:
右转,右转,左转,左转,右转,右转…左转,左转,右转,右转,右转。
即两次右转和两次左转交替出现的形式,最后两次右转(最后两次一定是
右转)后再多加一次右转。我们还知道,蚂蚁不会在同一个位置连续旋转两次,
并且蚂蚁行走的路径除了起点以外,不会到达同一个点多次,它最后一定是回
到起点然后结束自己的行程,而且蚂蚁只会在棋盘格子的顶点处转弯。
设 k为蚂蚁左转的次数除以2,当k=0 时,蚂蚁可能行走的路径如下图
转弯序列为:右转,右转,右转。
当 k=1 时,蚂蚁可能行走的路径如下图
转弯序列为:右转,右转,左转,左转,右转,右转,右转。
现在已知棋盘大小、每个格子的权值以及左转次数/2 的值,问蚂蚁走出
的路径围出的封闭图形,权值之和最大可能是多少。
输入描述 Input Description
在输入文件ant.in 中,第一行三个数n,m,k。意义如题目描述。
接下来一个n 行m 列的整数矩阵,表示棋盘。
输出描述 Output Description
一个数,表示蚂蚁所走路径围出的图形可能的最大权
值和。
样例输入 Sample Input
2 5 2
-1 -1 -1 -1 -1
-1 -1 -1 -1 -1
样例输出 Sample Output
-8
数据范围及提示 Data Size & Hint
【样例说明】
除了第一行的第二个和第一行的第四个都要围起来才至少合法。
【数据规模与约定】
10%的数据所有格子中权值均非负
另20%的数据n=2
另30%的数据k=0
100%的数据1≤n≤100,1≤m≤100,0≤k≤10 保证存在合法路径,数据有梯度,格子中每个元素的值绝对值不超过 10000
View Code
在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点
处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯
前走了多长。蚂蚁转弯是有一定特点的,即它的转弯序列一定是如下的形式:
右转,右转,左转,左转,右转,右转…左转,左转,右转,右转,右转。
即两次右转和两次左转交替出现的形式,最后两次右转(最后两次一定是
右转)后再多加一次右转。我们还知道,蚂蚁不会在同一个位置连续旋转两次,
并且蚂蚁行走的路径除了起点以外,不会到达同一个点多次,它最后一定是回
到起点然后结束自己的行程,而且蚂蚁只会在棋盘格子的顶点处转弯。
设 k为蚂蚁左转的次数除以2,当k=0 时,蚂蚁可能行走的路径如下图
转弯序列为:右转,右转,右转。
当 k=1 时,蚂蚁可能行走的路径如下图
转弯序列为:右转,右转,左转,左转,右转,右转,右转。
现在已知棋盘大小、每个格子的权值以及左转次数/2 的值,问蚂蚁走出
的路径围出的封闭图形,权值之和最大可能是多少。
输入描述 Input Description
在输入文件ant.in 中,第一行三个数n,m,k。意义如题目描述。
接下来一个n 行m 列的整数矩阵,表示棋盘。
输出描述 Output Description
一个数,表示蚂蚁所走路径围出的图形可能的最大权
值和。
样例输入 Sample Input
2 5 2
-1 -1 -1 -1 -1
-1 -1 -1 -1 -1
样例输出 Sample Output
-8
数据范围及提示 Data Size & Hint
【样例说明】
除了第一行的第二个和第一行的第四个都要围起来才至少合法。
【数据规模与约定】
10%的数据所有格子中权值均非负
另20%的数据n=2
另30%的数据k=0
100%的数据1≤n≤100,1≤m≤100,0≤k≤10 保证存在合法路径,数据有梯度,格子中每个元素的值绝对值不超过 10000
把题目意思稍微变一下,就是然你选出一个像长城一样的图形,包含的权值最大 我们很容易想到五维动归f[i1,j1,i2,j2,k](i1,j1,i2,j2表示第k个矩形的4个坐标值)(这个k是原来的2*k+1,转换了) 但是五维时间空间上都无法承受 通过五维动归转移的时候我们发现转移的限制条件只有4个,分别是k,这个矩形右下角的横坐标和纵坐标,这个矩形的高度 所以空间成功压到四维f[i,j,k,h] 但是按照原来的转移枚举右上角,其实时间还是五维 再仔细想想,我们必须枚举右上角吗 一个矩形其实是可以拆成一个个的长条的 对了,所以动归方程就出来了,还要一个辅助数组f2[i,j-1,k,h]记录可以转移到f[i,j,k,h]的值 f[i,j,k,h]:=max{f[i,j-1,k,h],f2[i,j-1,k,h]}+sum; 最后注意一下初值的设定 其实这个是刚好卡空间过了,可以把f[i,j,k,h]的i去掉循环用数组
var f:array[0..101,0..25,0..101]of longint; f2:array[0..101,0..25,0..101]of longint; sum:array[0..102,0..100]of longint; n,m,k,ans:longint; procedure init; var i,j,l,h:longint; begin read(n,m,k); k:=2*k+1; for i:=1 to n do for j:=1 to m do begin read(sum[i,j]); inc(sum[i,j],sum[i-1,j]); end; end; function max(x,y:longint):longint; begin if x>y then exit(x); exit(y); end; procedure work; var i,j,l,h:longint; begin ans:=-maxlongint; for i:=1 to n do begin fillchar(f,sizeof(f),1<<7); fillchar(f2,sizeof(f2),1<<7); for j:=1 to m do for h:=1 to i do f[j,1,h]:=sum[i,j]-sum[h-1,j]; for j:=1 to m do for l:=1 to k do if l and 1=1 then begin for h:=1 to i do f[j,l,h]:=max(max(f[j-1,l,h],f2[j-1,l-1,h+1])+sum[i,j]-sum[h-1,j],f[j,l,h]); for h:=1 to i do f2[j,l,h]:=max(f[j,l,h],f2[j,l,h-1]); end else begin for h:=1 to i do f[j,l,h]:=max(max(f[j-1,l,h],f2[j-1,l-1,h-1])+sum[i,j]-sum[h-1,j],f[j,l,h]); for h:=i downto 1 do f2[j,l,h]:=max(f[j,l,h],f2[j,l,h+1]); end; for j:=1 to m do for h:=1 to i do ans:=max(ans,f[j,k,h]); end; write(ans); end; begin init; work; end.
View Code
相关文章推荐
- 源代码(一系列人类可读的计算机语言指令)
- Mysql Innodb以及支持uft-8的默认设定
- 2012蓝桥杯预赛题-奇怪的比赛-递归实现
- Oracle 10g逻辑备份---ORA-39002、ORA-39070……
- 你们会选择“优雅降级”还是“渐进增强”的方式?
- 《高效学习OpenGL》 之 反馈 glFeedbackBuffer(), glPassThrough()
- 稀疏数组(Sparse array)
- 工具错误集锦
- 使用Jdom查询数据库后,把数据写入xml文件中
- autoit 清理进程,实用
- 字符串理论
- TCP异常关闭之总结
- android的m、mm、mmm编译命令的使用
- C使用FILE指针文件操作
- 关于Java的String.split方法的具体使用方法
- nginx服务器 301重定向主页 rewrite配置
- Android之观察者模式
- Android中的Handler, Looper, MessageQueue和Thread
- Hibernate实战_笔记2(Hibernate范未不匹配问题)
- WIN7里添加TELNET