ヒストグラム&& 51nod 1158サブマトリクスでHDU -1506最大の矩形が最大(単調スタック)、全て1であります

単調なスタックとキューは説明:ポータル

質問のHDU -1506意味:

あなたの四角形の一部高さを与えることですので、あなたは、矩形領域がこれらの矩形の最大値で構成することを数えます

上記のように被写体が増分全て与えられた場合、貪欲を解決するために使用することができます

最終的な高さの長方形の各高さは、その上に最大値から選択するように左から右へ

 

しかし、それが増加していない場合は、真ん中が低くなりますので、貪欲は捨てるより大きく、その完全な高さの前に取るためにポリシーを適用したいのですが、前にも、彼らが最終的な答えのために彼らの高さを実現可能なことはできません捨てるかを決定します私たちは構造のシーケンスを増加している、あなたはそれを維持するために、スタックを使用することができます

 

コード:

1の#include <stdio.hの>
 2の#include < ストリング・H>
 3の#include <iostreamの>
 4の#include <キュー>
 5の#include <アルゴリズム>
 6の#include <ベクトル>
 7の#include <積層>
 8  使って 名前空間STDを;
9  のconst  int型 MAXN = 100080 10  int型 N、高さ[MAXN]、幅[MAXN]、スタック[MAXN]、トップ= 0 11  長い 長い作業()
 12  {
 13      長い のANS = 0 14     以下のためにint型 i = 1 ; iが<= N + 1 ; ++ i)の
 15      {
 16          であれば(高さ[I]> スタック[トップ])
 17          {
 18              スタック[++トップ] = 高さ[I]。
19              幅[トップ] = 1 20          }
 21          他の
22          {
 23              INT widthsum = 0 24              一方(スタック[トップ]> 高さは、[I])
 25              {
 26                  + = widthsum 幅[トップ]。
27の                  ANS = MAX(ANS、(長い 長い)widthsum * スタック[トップ])。
28                  top-- ;
29              }
 30              スタック[++トップ] = 高さ[I]。
31              幅[トップ] = widthsum + 1 32          }
 33      }
 34の     リターンANS。
35  }
 36  のint main()の
 37  {
 38      ながら(〜のscanf(" %d個"、&N))
 39      {
 40の         場合(!n)をブレーク41          のためには、int型 i = 1 ; iが<= N; ++ I)
 42              のscanf(" %dの"、および高さ[I])。
43          高さ[N + 1 ] = 0 ;
44の         長い 長い ANS = 仕事();
45          のprintf(" %LLDする\ n " 、ANS)。
46      }
 47      リターン 0 48 }
コードの表示

 

ポータル:51nod 1158

質問の51nod 1158の意味:

入力は、あなたの1又は0で構成され、列mを、長方形の行nを与えることであり、あなたが最大値から塗りつぶされた四角形で見つけます

 

ソリューション:

質問と唯一の違いは、高にあなたの質問を教えてくれ、ですが、質問には自分自身を見つけるためにあなたを必要とし、前の質問に非常に似て感じます

アイデア:最初のステップは、マトリックスについて記載したように[I] [j]は、i番目の動作の全体ヒストグラムハイエンドに記録して、次元削減動作です。

 

1 1 1 0

0 0 1 1

1 1 0 1

1 1 1 0

上記のために我々はにそれを置くことができること

1 1 1 0

0 0 2 1

1 1 0 2

2 2 1 0

そして、それについての質問に、この処理の後に、それぞれの行は、その行のデータ入力上の問題と等価であるので、我々はそれで、この単調なスタック処理11のわずか数行を必要とします

 

コード:

1つの#include <ビット/ STDC ++ H>
 2  
3  使用して 名前空間STDを、
4  
5  のconst  int型 N = 1E5 + 7 6  
7  INTのN、M、X、ANS。
8  
9  のint H [N]、[N]。
10  
11スタック< INT > S。
12  
13  のint main()の
 14  
15  {
 16  
17      のscanf(" %D%dの"、&​​M、&N)
18  
19      のためにINT I = 0; 私は<M。私は++ 20  
21      {
 22  
23          のためにINT J = 1、J <= N; J ++ 24  
25          {
 26  
27              のscanf(" %dの"、およびX)
28  
29              であれば(x == 1)[J] + = 1 ;
30  
31               [J] = 0 ;
32  
33              H [J] = [J]。
34  
35          }
 36  
37          s.push(0 );
 38である 
39          のためにINT J = 1 ; J <= N + 1。 J ++; 40  
41れている         {
 42は 
43である             一方で(H [J] < H [s.top()])
 44は 
45              {
 46である 
47                  int型のインデックス= s.top();
 48  
49                  s.pop();
 50  
51は、                 int型( - J TMP = 1 - s.top())* H [インデックス]; // 我々がインクリメントさ保つため、
 52                  // 配列を今の位置にスタックの高さの上部との間のすべての位置で、この位置を列挙
 53                  //この高さ位置よりも大きくされている列挙
54はある                  ANS = 、MAX(ANS、TMP)
 55  
56である             }
 57である 
58              s.push(J);
 59  
60          }
 61である 
62である     }
 63が 
64      COUT ANS << << ENDL;
 65  
66 }
コードの表示

 

おすすめ

転載: www.cnblogs.com/kongbursi-2292702937/p/11277980.html