zoukankan      html  css  js  c++  java
  • POJ 2082 题解

    Terrible Sets
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 5330   Accepted: 2715

    Description

    Let N be the set of all natural numbers {0 , 1 , 2 , . . . }, and R be the set of all real numbers. wi, hi for i = 1 . . . n are some elements in N, and w0 = 0. 
    Define set B = {< x, y > | x, y ∈ R and there exists an index i > 0 such that 0 <= y <= hi ,∑0<=j<=i-1wj <= x <= ∑0<=j<=iwj} 
    Again, define set S = {A| A = WH for some W , H ∈ R+ and there exists x0, y0 in N such that the set T = { < x , y > | x, y ∈ R and x0 <= x <= x0 +W and y0 <= y <= y0 + H} is contained in set B}. 
    Your mission now. What is Max(S)? 
    Wow, it looks like a terrible problem. Problems that appear to be terrible are sometimes actually easy. 
    But for this one, believe me, it's difficult.

    Input

    The input consists of several test cases. For each case, n is given in a single line, and then followed by n lines, each containing wi and hi separated by a single space. The last line of the input is an single integer -1, indicating the end of input. You may assume that 1 <= n <= 50000 and w1h1+w2h2+...+wnhn < 109.

    Output

    Simply output Max(S) in a single line for each case.

    Sample Input

    3
    1 2
    3 4
    1 2
    3
    3 4
    1 2
    3 4
    -1

    Sample Output

    12
    14

    Source

     
    题意:给一排高度不同底部在同一水平线的连续矩形,在形成的总区域内寻找面积最大的矩形子区域。
    思路一:枚举答案区域的最高点,也就是遍历所有小矩形,并以当前小矩形的高度为最终高度,找到左右方向课扩展的最大范围即可,复杂度n^2。因为太暴力了,没有写,据说可以过...
    思路二:优化一下思路一,在寻找最大可扩展边界时,因为可扩展性是单调的,所以我们可以二分区间端点然后用某种数据结构求出区间最小值即可。我是二分+线段树,复杂度n*log^2。TLE了。
      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <set>
     14 #include <map>
     15 #include <list>
     16 #include <iomanip>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <bitset>
     20 #include <ctime>
     21 
     22 using namespace std;
     23 
     24 #define pau system("pause")
     25 #define ll long long
     26 #define pii pair<int, int>
     27 #define pb push_back
     28 #define mp make_pair
     29 #define clr(a, x) memset(a, x, sizeof(a))
     30 
     31 const double pi = acos(-1.0);
     32 const int INF = 0x3f3f3f3f;
     33 const int MOD = 1e9 + 7;
     34 const double EPS = 1e-9;
     35 
     36 /*
     37 #include <ext/pb_ds/assoc_container.hpp>
     38 #include <ext/pb_ds/tree_policy.hpp>
     39 
     40 using namespace __gnu_pbds;
     41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
     42 */
     43 
     44 int n;
     45 struct rec {
     46     ll w;
     47     int h;
     48 } R[50015];
     49 int mi[200015];
     50 void pushup(int i) {mi[i] = min(mi[i << 1], mi[i << 1 | 1]);}
     51 void build(int i, int l, int r) {
     52     if (l == r) {
     53         mi[i] = R[l].h;
     54         return;
     55     }
     56     int mi = l + r >> 1;
     57     build(i << 1, l, mi);
     58     build(i << 1 | 1, mi + 1, r);
     59     pushup(i);
     60 }
     61 int query(int i, int l, int r, int x, int y) {
     62     if (x <= l && r <= y) {
     63         return mi[i];
     64     }
     65     int res1 = MOD, res2 = MOD, mi = l + r >> 1;
     66     if (x <= mi) res1 = query(i << 1, l, mi, x, y);
     67     if (mi < y) res2 = query(i << 1 | 1, mi + 1, r, x, y);
     68     return min(res1, res2);
     69 }
     70 int main() {
     71     R[0].w = 0, R[0].h = -1;
     72     while (~scanf("%d", &n) && ~n) {
     73         ll ans = 0;
     74         for (int i = 1; i <= n; ++i) {
     75             scanf("%lld%d", &R[i].w, &R[i].h);
     76             R[i].w += R[i - 1].w;
     77         }
     78         build(1, 0, n);
     79         for (int i = 1; i <= n; ++i) {
     80             int s1 = 0, e1 = i - 1, m1, res1 = i;
     81             while (s1 <= e1) {
     82                 m1 = s1 + e1 >> 1;
     83                 if (query(1, 0, n, m1, i - 1) < R[i].h) {
     84                     s1 = m1 + 1;
     85                 } else {
     86                     e1 = (res1 = m1) - 1;
     87                 }
     88             }
     89             int s2 = i + 1, e2 = n, m2, res2 = i;
     90             while (s2 <= e2) {
     91                 m2 = s2 + e2 >> 1;
     92                 if (query(1, 0, n, i + 1, m2) < R[i].h) {
     93                     e2 = m2 - 1;
     94                 } else {
     95                     s2 = (res2 = m2) + 1;
     96                 }
     97             }
     98             ans = max(ans, R[i].h * (R[res2].w - R[res1 - 1].w));
     99         }
    100         printf("%lld
    ", ans);
    101     }
    102     return 0;
    103 }

    思路三:维护一个高度递增的单调栈,每次新加入矩形时,弹出所有高度比他大的矩形同时求出弹出范围矩形所能形成的最大值。维护结束后再枚举栈内元素作为矩形区域左端点即可。复杂度O(n)。

     1 #include <iostream>
     2 #include <fstream>
     3 #include <sstream>
     4 #include <cstdlib>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <string>
     8 #include <cstring>
     9 #include <algorithm>
    10 #include <queue>
    11 #include <stack>
    12 #include <vector>
    13 #include <set>
    14 #include <map>
    15 #include <list>
    16 #include <iomanip>
    17 #include <cctype>
    18 #include <cassert>
    19 #include <bitset>
    20 #include <ctime>
    21 
    22 using namespace std;
    23 
    24 #define pau system("pause")
    25 #define ll long long
    26 #define pii pair<int, int>
    27 #define pb push_back
    28 #define mp make_pair
    29 #define clr(a, x) memset(a, x, sizeof(a))
    30 
    31 const double pi = acos(-1.0);
    32 const int INF = 0x3f3f3f3f;
    33 const int MOD = 1e9 + 7;
    34 const double EPS = 1e-9;
    35 
    36 /*
    37 #include <ext/pb_ds/assoc_container.hpp>
    38 #include <ext/pb_ds/tree_policy.hpp>
    39 
    40 using namespace __gnu_pbds;
    41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
    42 */
    43 
    44 struct rec {
    45     int w;
    46     int h;
    47 } R[50015];
    48 int n;
    49 stack<int> sta;
    50 int main() {
    51     R[0].w = 0, R[0].h = -1;
    52     sta.push(0);
    53     while (~scanf("%d", &n) && ~n) {
    54         for (int i = 1; i <= n; ++i) {
    55             scanf("%d%d", &R[i].w, &R[i].h);
    56             R[i].w += R[i - 1].w;
    57         }
    58         int ans = 0;
    59         for (int i = 1; i <= n; ++i) {
    60             int we = R[i - 1].w;
    61             while (R[sta.top()].h >= R[i].h) {
    62                 int x = sta.top();
    63                 sta.pop();
    64                 int y = sta.top();
    65                 ans = max(ans, R[x].h * (we - R[y].w));
    66             }
    67             int x = sta.top();
    68             ans = max(ans, R[i].h * (R[i].w - R[x].w));
    69             sta.push(i);
    70         }
    71         int we = R[sta.top()].w;
    72         while (sta.size() > 1) {
    73             int x = sta.top();
    74             sta.pop();
    75             int y = sta.top();
    76             ans = max(ans, R[x].h * (we - R[y].w));
    77         }
    78         printf("%d
    ", ans);
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    Objective-C入门教程03:属性(@property和@synthesize)
    iOS 开发的9个超有用小技巧
    oc关于非原子属性
    如果局部变量与实例变量同名,那么如何在局部变量的作用域内引用实例变量?
    从0开始搭建vue+webpack脚手架(一)
    ES6学习之 解构赋值
    Vue+webpack项目中实现跨域的http请求
    Vuejs核心思想学习笔记
    更改file文件上传默认CSS样式
    javascript获取style兼容性问题
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8468083.html
Copyright © 2011-2022 走看看