トピック:https://ac.nowcoder.com/acm/contest/888/A
質問の意味:フル1行列の番号を見つけ、この行列は、全体の他のフル行列は1が含まれていません
アイデア:チーム全体の賃金が言います
- > {
この種の問題は、一般的な解決策は二つの方向にあります。
一次元圧縮、即ち、列挙の上下の境界、及びOの複雑さ(N ^ 3)。
B:看板問題、すなわち、下部境界列挙sは、sは、それほど長い背の高い端の一部として見たビルボード上に配置した後に上昇、O(N ^ 2)の複雑され得ます。
}
ここでは、確かに見ることができ、我々はすでに前に各行列を取得する方法を知っているクラスBの複雑さを見て、私たちは彼が実際には、我々は現在の行列かどうかを確認するにはより多くの何もない、それの最大の行列の拡張機能ではないことを確認する方法を作るのですかまた、左右、上下に適用するように拡張することができ、我々は、[i]は、R [i]は、我々が考慮されていない上記の拡張アプリケーションを列挙するために、トップからダウンしているだろうLを見つけることができ、DPとスタックアプローチの前に見てきました我々はアウトを事前に、我々は現在のレベルが、彼らは枝以下そのときの端を適用する方法であるかどうかを決定する必要があります。私たちは1、矩形の数を、彼らは枝が適用できることを意味し、そうでない場合に解釈すれば、それをどのように決定するか、その後、1ができるすべてで、あなたができるので、判断は、間隔のプレフィックス長さに等しい、このラインを見ています
<ビット/ STDC ++ H>の#include の#define MAXN 3005 の#define MOD十億七 使用 名前空間STDを、 typedef int型LL。 LL N、M。 チャーSTR [MAXN] [MAXN]。 LL DP [MAXN] [MAXN]。 int型VIS [MAXN] [MAXN]。 [MAXN]、L [MAXN]和[MAXN] R LL。 LLのCNT; LL Q [MAXN]、ヘッドと ボイド GET(INT T){ ヘッド = 0 ; Q [++ヘッド] = 0 ; 以下のために(int型 I = 1 ; I <= M; iは++ ){ 一方(ヘッド> 0&& DP [T] [I] <= DP [T] [Q [頭部]])head-- 。 L [I] = Q [ヘッド] + 1 。 Q [ ++ヘッド] = I。 } ヘッド = 0 ; Q [++ヘッド= M + 1 。 以下のために(int型 I = mを、I> = 1 ; i-- ){ 一方(ヘッド> 0 && DP [T] [I] <= DP [T] [Q [頭部]])head-- 。 R [I] = Q [ヘッド] - 1 。 Q [ ++ヘッド] = I。 } のための(int型 I = 1 ; I <= M; I ++)は和[I] =和[I- 1] +(STR [T + 1 I] ==] [ ' 1 ' )。 以下のために(int型 I = 1 ; I <= M; iは++ ){ 場合(DP [T] [I] == 0)続けます。 もし(VIS [L [I] [R [I]] == t)を続けます。 もし(和[R [I]] -和[L [I] - 1 ] == R [I] -1- [I] + 1)続けます。 CNT ++ ; VIS [L [I] [R [I] = T。 } } int型のmain(){ scanf関数(" %D%D "、&N、&M)。 以下のために(int型私= 1 iが++; iが<= N ){ scanf関数(" %sの"、STR [I] + 1 )。 } のための(int型 i = 1 ; iが<= N; iが++ ){ ため(INT J = 1 ; J <= Mであり、j ++ ){ 場合(STR [i]は[J] == ' 1 ' ){ DP [I ] [J] = DP [I- 1 ] [J] + 1 ; } 他の DP [I] [J] = 0 。 } } のために(int型 I = 1は iが++; iがn = < {) を取得(i)を、 } のprintf(" %dの" 、CNT)。 リターン 0 ; }