【問題描述】
為了增添公園的景致,現在需要在公園中修築乙個花壇,同時在畫壇四周修建一片綠化帶,讓花壇被綠化帶圍起來。
如果把公園看成乙個m*n的矩形,那麼花壇可以看成乙個c*d的矩形,綠化帶和花壇一起可以看成乙個a*b的矩形。
如果將花園中的每一塊土地的「肥沃度」定義為該塊土地上每乙個小塊肥沃度之和,那麼,
綠化帶的肥沃度=a*b塊的肥沃度-c*d塊的肥沃度
為了使得綠化帶的生長得旺盛,我們希望綠化帶的肥沃度最大。
【輸入】:
第一行有6個正整數m,n,a,b,c,d
接下來乙個m*n的數字矩陣,其中矩陣的第i行j列元素為乙個整數xij,表示該花園的第i行第j列的土地「肥沃度」。
【輸出】:
乙個正整數,表示綠化帶的最大肥沃程度。
【輸入輸出樣例】
parterre.in
4 5 4 4 2 2
20 19 18 17 16
15 14 13 12 11
10 9 8 7 6
5 4 3 2 1
parterre.out
132【資料範圍】
30%的資料,1<=m,n<=50
100%的資料,1<=m,n<=1000,1<=a<=m,1<=b<=n,1<=c<=a-2,1<=d<=b-2,1<=「肥沃度」<=100
考慮答案為乙個a*b矩陣權值和-其中最小c*d矩陣權值和
先拿單調佇列滑出來第i,j-b+1 -> i,j格最小矩陣和
在拿單調佇列維護上述最小矩陣和 那麼可以處理出i-a+1,j-b+1 -> i,j格最小子矩陣 再更新答案
時間複雜度o(n*m)
#include #include #include #include using namespace std;
const int maxn=1000+10;
int a[maxn][maxn];
int v[maxn][maxn];
int f[maxn][maxn];
dequeq;
int main()
memset(v,127/2,sizeof(v));
for(int i=c;i<=m;i++)
while(!q.empty()&&f[i][q.back()]>=f[i][j])
q.pop_back();
q.push_back(j);
} }int ans=0;
for(int j=d;j<=n;j++)
while(!q.empty()&&v[q.back()][j]>=v[i][j])
q.pop_back();
q.push_back(i);
} }printf("%d\n",ans);
/*for(int i=1;i<=m;i++)*/
return 0;
}
HAOI2007 修築綠化帶
haoi2007 修築綠化帶 時間限制 1 s 記憶體限制 128 mb 問題描述 為了增添公園的景致,現在需要在公園中修築乙個花壇,同時在畫壇四周修建一片綠化帶,讓花壇被綠化帶圍起來。如果把公園看成乙個m n的矩形,那麼花壇可以看成乙個c d的矩形,綠化帶和花壇一起可以看成乙個a b的矩形。如果將...
題解 HAOI2007 修築綠化帶
題目意思比較簡單,就不在這裡贅述了 本著練習平衡樹的思路,我把方法嘗試往上面去套,結果想不出 只能棄掉平衡樹 最後想出來的方法是這樣的 我們運用類似於高維字首和那樣一維一維加上去的方法 先橫著統計在某個範圍內和最小的 c d 矩陣,把貢獻算在範圍的右下角 注意,這裡保證了這個矩陣在以 i,j 為右下...
HAOI2007 修築綠化帶 題解
題意分析 給出乙個 m n 的矩陣 a 要求從中選出乙個 a b 的矩陣 b 再從矩陣 b 中選出乙個 c d 的矩陣 c 要求矩陣 b,c 的邊界不能重合,求矩陣 c 在矩陣 b 中的補集的權值和的最大值。思路分析 通過分析題目後可以發現本題可以用二維單調佇列進行求解,同時利用到了二維字首和。即先...