zoukankan      html  css  js  c++  java
  • 算法问题实战策略 FENCE

    地址 https://algospot.com/judge/problem/read/FENCE

    开始考虑暴力遍历

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

    后面优化 采取分冶的办法  最大值要么在左边 要么在右边 要么经过左右 三种情况。

    左右两种情况采取递归的方式进行计算 

    穿越分界由左到右的情况则采用以下方法计算:

    取中间两块木板 长方形长度为2 高度为两筐木板短的那块,然后向两边扩展,选取左边或者右边较高的那块木板扩展.每次扩展计算面积,记录当前最大面积。最后得到穿越分界由左到右的最大面积

    之所以会取较高的木板扩展是因为面积要以最低的高度计算 如果两边扩展不取较高的而是取较低的木板 那么如果扩展的木板低于当前高度 会遗漏一些情况未计算面积 从而产生错误.

    代码如下:

     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 }
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    模板方法模式
    备忘录模式
    观察者模式
    中介者模式
    迭代器模式
    Char型和string型字符串比较整理
    命令模式
    责任链模式
    代理模式
    dokcer 杂谈
  • 原文地址:https://www.cnblogs.com/itdef/p/11745743.html
Copyright © 2011-2022 走看看