3111: [Zjoi2013]螞蟻尋路 - BZOJ


題目描述 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去掉循環用數組


 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.
View Code

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: