まず、行列の左上隅を見つけることは容易で、R * C行列の適格性を判断するために、他のヒットは何もすることはできませんどのように検討し、行列Rの左上隅が必要です* C共感常にメダルた後、要素の角を左にトップを超えることはできません。最も&左端の非ゼロ点が微分を最適化するために使用することができるため、複雑さが$ Oであり(N ^ {4} )$(N 及びMは同じオーダーである)
列挙剪定に下降、次いで(プラスいくつか割り切れます)生きることができる
正の解が最大列挙1×C行列、最大行列Rの列挙* 1、R * C行列は答え(メンテナンスとの差)であるようなものである
本の正しさを証明するためには、分割さ二つの部分を考えてみます
。1. R * C行列は法的行列を起動することができることを必要1 * Cとr * 1合法的な、明らかにc倍R *は1 / r倍*行列C 1のマトリックスと(セットアップ)
2.十分、すなわちマトリックス1 * cおよびR * 1法的Rを起動することができ* Cマトリクス正規、現在の左上隅を考慮し、次に不可避、xの過剰で、各列を示し、端部に倍の数xをノック各行が少なくともX、すなわちA行列のR * C X回ノックノック引き起こす可能性
証明書を取得する問題を、次いで、最終溶液の複雑さが(N ^ {3} O正$であった $(N) 及びmと同じ順序であります )
1の#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 INT N、M、S、ANS、[ 105 ] [ 105 ]、B [ 105 ] [ 105 ]。 4 ブール PD(INT R、INT C){ 5 のmemcpy(B、、はsizeof (a)参照)。 6 用(INT iが= 1 ; iが<= N; I ++ ) 7 用(INT J = 1 ; J <= Mであり、j ++ ) 8 もし(B [I] [J]){ 9 もし((I + R- 1 > N)||(J + C- 1 > M))戻り 0 ; 10 INT P = B [i]は[J]。 11 のために(INT X ++; X <I + R X = I ) 12 のための(int型の Y = J; Y <J + C、Y ++ ) 13 であれば((B [X] [Y] - = P)< 0)リターン 0 ; 14 } 15 リターン 1 。 16 } 17 INT メイン(){ 18 のscanf(" %D%D "、&N、&M)。 19 のために(INT iは= 1 ; iが<= N; I ++ ) 20 のための(INT J = 1 ; J <= Mであり、j ++ ){ 21 のscanf(" %dの"、および[I] [J])。 22の S + = [I] [J]。 23 } 24 のために(INT iは、N =; I; i-- ) 25 のための(INT J = M; J; j-- ) 26 であれば((S%(I * J)== 0)&&(I * jが> ANS)&&(PD(I、J)))ANS = I * J。 27 のprintf(" %がd "、S / ANS)。 28 }