题目描述 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
把题目意思稍微变一下,就是然你选出一个像长城一样的图形,包含的权值最大 我们很容易想到五维动归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去掉循环用数组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 var 2 f:array[0..101,0..25,0..101]of longint; 3 f2:array[0..101,0..25,0..101]of longint; 4 sum:array[0..102,0..100]of longint; 5 n,m,k,ans:longint; 6 7 procedure init; 8 var 9 i,j,l,h:longint; 10 begin 11 read(n,m,k); 12 k:=2*k+1; 13 for i:=1 to n do 14 for j:=1 to m do 15 begin 16 read(sum[i,j]); 17 inc(sum[i,j],sum[i-1,j]); 18 end; 19 end; 20 21 function max(x,y:longint):longint; 22 begin 23 if x>y then exit(x); 24 exit(y); 25 end; 26 27 procedure work; 28 var 29 i,j,l,h:longint; 30 begin 31 ans:=-maxlongint; 32 for i:=1 to n do 33 begin 34 fillchar(f,sizeof(f),1<<7); 35 fillchar(f2,sizeof(f2),1<<7); 36 for j:=1 to m do 37 for h:=1 to i do 38 f[j,1,h]:=sum[i,j]-sum[h-1,j]; 39 for j:=1 to m do 40 for l:=1 to k do 41 if l and 1=1 then 42 begin 43 for h:=1 to i do 44 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]); 45 for h:=1 to i do 46 f2[j,l,h]:=max(f[j,l,h],f2[j,l,h-1]); 47 end 48 else 49 begin 50 for h:=1 to i do 51 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]); 52 for h:=i downto 1 do 53 f2[j,l,h]:=max(f[j,l,h],f2[j,l,h+1]); 54 end; 55 for j:=1 to m do 56 for h:=1 to i do 57 ans:=max(ans,f[j,k,h]); 58 end; 59 write(ans); 60 end; 61 62 begin 63 init; 64 work; 65 end.