質問の意味:https://www.luogu.com.cn/problem/P1108
二つの数を構成列の同じ数であれば、我々は、2つの同一の列と言います。
最長のシーケンスの減少の数を見つけるためのプログラム。
問題の解決策 wjyyy偉大な神。
DP プロセス、F 格納された配列は、最長シーケンスの減少の長さF 添字FアレイiがあるI 、(最後の外側を除く)最も長いシーケンスドロップデータが失われた、エンド手段一緒にプログラム番号かどうかを決定する際に、したがって、もはや適用されません。
我々は最初から見て、
- 同じ番号の最初の行の列の別の番号を有する第一の数の数が、それは今、すなわち、一方は削除することができ、それらが等しい判断できる場合(処理コードであるT [J] = 0 )。その裏に別の番号に接続されており、彼らはお互いに影響を与えることはありません2つのシリーズ、と判断することができます。2つの列は、列からの等しい数から転送することができるので
- それらは等しくないので、最初の番号からの行の異なる列の別の番号、および等しくない、バック追加どのように関係なく、すなわち、削除されないと最初の数字の数は、次いで、従来の判断に従って進みます。
上記の二つの点から、我々は繰り返し、この防止ダブルカウントを削除しました。
#include <ビット/ STDC ++ H.> 使用して 名前空間STD; の#define MAX(A、B)(A> B A:?B) のint A [ 5009 ]、F [ 5009 ]、T [ 5009 ]; // A [ i]は株価の対象である、F [i]が最長日iの長さである 。// T [i]はiはプログラムの終了である int型のmain() { int型 N-、MAXN = 0 ; CIN >> N-。 用(INT I = 1 ; I <= N; I ++)CIN >> A [I]、F [I] = 1 ; のための(INT I = 1 ; I <= N; I ++ ) { 用(のInt Jは= 1。 ; J <I、J ++ ) { IF(A [I] < A [J]) F [I] = MAX(F [I]、F [J] + 。1 ); } //は今最長は通常減少配列シーク MAXN = MAX(MAXN、F [I]を); //は最長の長さを注意 するために(INT J = 1。 ; J <I、J ++ ) { IF(F [I] == F [J] && A [I] == A [J])// 同じ長さと同一の列数 T [J] = 0 ; 他 IF(F [I] == F [J] + 。1 && A [I] <A [J])// の前に接続することができます。 T [I] + = T [J]。 } もし(T [i]が!)T [I] = 1。// 为了后面的数转移 } INT ANS = 0 。 以下のために(INT iが= 1 ; I <= N; I ++ ) であれば(F [I] == MAXN)ANS + = T [i]は、 coutの << MAXN << " " << ANS; }