HAOI2007 修築綠化帶 題解

2022-05-27 15:03:18 字數 1264 閱讀 3643

題意分析

給出乙個 $m*n$ 的矩陣 $a$ ,要求從中選出乙個 $a*b$ 的矩陣 $b$ ,再從矩陣 $b$ 中選出乙個 $c*d$ 的矩陣 $c$ ,要求矩陣 $b,c$ 的邊界不能重合,求矩陣 $c$ 在矩陣 $b$ 中的補集的權值和的最大值。

思路分析

通過分析題目後可以發現本題可以用二維單調佇列進行求解,同時利用到了二維字首和。即先對其中一維進行求解,然後再求解另一維。

具體實現

1. 預處理二維字首和

設 $suml_$ 表示以 $(i,j)$ 為右下角的矩形 $b$ 的權值和, $sums_$ 表示以 $(i,j)$ 為右下角的矩形 $c$ 的權值和,$sum_$ 表示 $(i,j)$ 的二維字首和。遞推式顯然,就不贅述了。

2. 利用單調佇列求解列的答案

設 $f1_$ 表示以 $(i,j-b+d+1\sim j-1)$ 為右下角的矩陣 $c$ 中權值和的最大的矩陣,則對於每個 $j$ ,有:

3. 利用單調佇列求解列的答案

設 $f2_$ 表示以 $(i-a+c+1\sim i,j-b+d+1\sim j-1)$ 為右下角的矩陣 $c$ 中權值和的最大的矩陣,求解過程與上步類似,就不贅述了。

4. 遍歷一遍找出答案

此時 $suml_-f2_$ 就是以 $(i,j)$ 為右下角的矩陣 $b$ 的答案,遍歷所有矩陣 $b$ ,找出最大值即可。

有乙個需要注意的點,矩陣 $b,c$ 的邊界不能重合,在遞推的時候下標需要注意。舉例:$(c,d)$ 不能作為決策和答案,$(c+1,d+1)$ 只能作為決策而不能作為答案。

#include#include#includeusing namespace std;

const int n=1100;

int m,n,a,b,c,d,ans;

int s[n][n],sum[n][n],suml[n][n],sums[n][n],f1[n][n],f2[n][n];

dequeq;

int main()

}//求解第一維

for(int j=b;j<=n;j++)

}//求解第二維

for(int i=a;i<=m;i++)

for(int j=b;j<=n;j++)

ans=max(ans,suml[i][j]-f2[i][j]); //找出答案

printf("%d",ans);

return 0;

}

HAOI2007 修築綠化帶

haoi2007 修築綠化帶 時間限制 1 s 記憶體限制 128 mb 問題描述 為了增添公園的景致,現在需要在公園中修築乙個花壇,同時在畫壇四周修建一片綠化帶,讓花壇被綠化帶圍起來。如果把公園看成乙個m n的矩形,那麼花壇可以看成乙個c d的矩形,綠化帶和花壇一起可以看成乙個a b的矩形。如果將...

HAOI2007 修築綠化帶

問題描述 為了增添公園的景致,現在需要在公園中修築乙個花壇,同時在畫壇四周修建一片綠化帶,讓花壇被綠化帶圍起來。如果把公園看成乙個m n的矩形,那麼花壇可以看成乙個c d的矩形,綠化帶和花壇一起可以看成乙個a b的矩形。如果將花園中的每一塊土地的 肥沃度 定義為該塊土地上每乙個小塊肥沃度之和,那麼,...

題解 HAOI2007 修築綠化帶

題目意思比較簡單,就不在這裡贅述了 本著練習平衡樹的思路,我把方法嘗試往上面去套,結果想不出 只能棄掉平衡樹 最後想出來的方法是這樣的 我們運用類似於高維字首和那樣一維一維加上去的方法 先橫著統計在某個範圍內和最小的 c d 矩陣,把貢獻算在範圍的右下角 注意,這裡保證了這個矩陣在以 i,j 為右下...