地址 https://algospot.com/judge/problem/read/FENCEios
開始考慮暴力遍歷ide
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 6 using namespace std; 7 8 int n; 9 int m; 10 11 vector<int> h; 12 13 int func() 14 { 15 int ret = 0; 16 17 for (int i = 0; i < h.size(); i++) { 18 int minHeight = h[i]; 19 for (int j = i; j < h.size(); j++) { 20 minHeight = min(minHeight,h[j]); 21 ret = max(ret, (j - i + 1)*minHeight); 22 } 23 } 24 25 return ret; 26 } 27 28 int main() 29 { 30 cin >> n; 31 32 while (n--) { 33 h.clear(); 34 m = 0; 35 cin >> m; 36 37 for (int i = 0; i < m; i++) { 38 int t; 39 cin >> t; 40 h.push_back(t); 41 } 42 43 cout << func() << endl; 44 } 45 46 return 0; 47 }
後面優化 採起分冶的辦法 最大值要麼在左邊 要麼在右邊 要麼通過左右 三種狀況。優化
左右兩種狀況採起遞歸的方式進行計算 spa
穿越分界由左到右的狀況則採用如下方法計算:code
取中間兩塊木板 長方形長度爲2 高度爲兩筐木板短的那塊,而後向兩邊擴展,選取左邊或者右邊較高的那塊木板擴展.每次擴展計算面積,記錄當前最大面積。最後獲得穿越分界由左到右的最大面積blog
之因此會取較高的木板擴展是由於面積要以最低的高度計算 若是兩邊擴展不取較高的而是取較低的木板 那麼若是擴展的木板低於當前高度 會遺漏一些狀況未計算面積 從而產生錯誤.遞歸
代碼以下:ci
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 6 using namespace std; 7 8 9 int n; 10 int m; 11 vector<int> h; 12 int solve(int left, int right) 13 { 14 if (left == right) return h[left]; 15 int mid = (left + right) / 2; 16 int ret = max(solve(left, mid), solve(mid + 1, right)); 17 18 int lo = mid, hi = mid + 1; 19 int height = min(h[lo], h[hi]); 20 ret = max(ret, height * 2); 21 while (left < lo || hi < right) { 22 if (hi < right && (lo == left || h[lo - 1] < h[hi + 1])) { 23 ++hi; 24 height = min(height,h[hi]); 25 } 26 else { 27 --lo; 28 height = min(height,h[lo]); 29 } 30 ret = max(ret, height*(hi - lo + 1)); 31 } 32 return ret; 33 } 34 35 36 int main() 37 { 38 cin >> n; 39 40 while (n--) { 41 h.clear(); 42 m = 0; 43 cin >> m; 44 for (int i = 0; i < m; i++) { 45 int t; 46 cin >> t; 47 h.push_back(t); 48 } 49 50 cout << solve( 0, m-1) << endl; 51 } 52 53 return 0; 54 }