なしプログラム番号の場合、この質問は非常に水、最長のドロップシーケンスを産みました。
しかし、それはそう、プログラムの数を持っています...
一つは、ダルマのためのプログラムの数です。
$ Fを設け[I]答えは> [I]、1 [j]を$場合$ [i]は、最長シーケンスの$端ドロップ長は、$ができる$ N ^ 2 $$ DP $です< = J <= I-1 $、[I] = MAX(F [I]、F [J] +1)$、量の一般的$ Fを更新することができます
場合$ S [i]は$最長$ [i]は$である$実施形態設け$ S [i]は$ [i]は$方法fを更新し、終了シーケンスの数を減少させ、更新することができます。
$ F [i]を== F [j]が+ 1 $、そして$ S [i]は= S [J] $の場合
[j]は、F $ F [i]を== $、そして$ S [i]が+ = S [J] $の場合
$ $ lenを、全ての$ F [I] == LENを減少させるために最長シーケンスの長さを取得した後$ $ S [i]は$全て一緒に、プログラムの総数です。
しかし、定義は$ S [i]は$である$ [i]は$、最長シーケンス衰退のプログラム番号を終了最長の配列情報は、失われた可能性が高い繰り返し、例えばされた減少です。
3 2 1 3 2 1
$ 3 $番号$ S []は$が$ 0 $になるべきであることの背後にある
、さもなければ$ 1 $、$ 2 $、$ 3 $シリーズ$ 321 $、$ 1 $、$ 2 $、$ 6 $を構成する一連$ 321 $計算を構成します繰り返しのプログラム番号。
したがって、二つの位置F $ [] $と$ S [] $である等しい、彼はその位置に設定されているときに$ 0 $
これを行うには、その後、状況はそれをパンします。
6 5 4 6 5 3
ここでは、以前の$ 5 $移転からも$ 0 $、$ 3 $の後にプログラム番号のセットの後に$ 5 $を置くとして、私は二つの場所から$ 3 $を作る場合、それは疲れてプラス答えている、それがパンになる、ではありません。
$も高い精度を使用するので、バーストint128プログラムの数は$ $ $長い長い$、$ _を破裂されますがあります。私は、直接パッケージ構造を形成するために:
https://www.cnblogs.com/lyttt/p/11805335.html
(ブログを参照してください)
1 // いい 2 / * 3 ID:Starry21 4 LANG:C ++ 5 TASK:buylow 6 * / 7の#include <cstdioを> 8の#include <アルゴリズム> 9の#include <ベクトル> 10の#include <CStringの> 11の#include < climits> 12 使って 名前空間はstdを、 13 の#define N 5005 14 の#define ML 505 // MaxLenth 15 の#defineは長い長いっ 16 の#define INF 0x3f3f3f3f 17 構造体 BT // のBigInt 18 { 19 のint A [ML]、lenの; 20 BT()// 初始化 21 { 22 のmemset(0、はsizeof ())。 23 LEN = 1 。 24 } 25 ボイドは、init() 26 { 27 [ 0 ] = 1 ; 28 } 29 のBT 演算子(+ CONST BT&A)CONST 30 { 31は、 BT Bは、 32 B.len = MAX(、A.len LEN); 33である ため(INT I = 0 ; I <B.len; I ++ ) 34である { 35 のBa [I] = Aaの+ [I] +のA [I]、 36 IF(BAの[I]> = 10 ) 37 { // 10運ぶ9 + 9 = 18キャリーせいぜい 38がなく Baから[I] - = 10 ; 39 のBa [I +の。1 ] ++ ; 40 } 41である } 42は、 IF(BA [B.len]中)// 次のものへ進む 43は B.len ++ ; 44は、 リターンB; 45 } 46は、 ボイドを読む() 47 { 48 チャーD [ML]; 49 scanfの(" %のS " 、D) ; 50 int型 L = strlenを(D) 51である ため(INT I = 0 ;私は<Lは、I ++ ) 52である A [I] = D [LI- 1 ] - ' 0 ' ; 53である lenは= L。 54 } 55 ボイドライト() 56 { 57 のために(INT I = len- 1 ; I> = 0 ; i-- ) 58 のprintf(" %dの" 、[I])。 59 } 60 }。 61 LLのRD() 62 { 63 = 1LL、X = F LL 0。チャー C = GETCHAR()。 64 一方、(C < ' 0 ' || C> ' 9 '){ もし、(C ==' - ')、F = - 1 ; C = GETCHAR();} 65 ながら(C> = ' 0 ' && C <= ' 9 '){X =(x << 3)+(X << 1)+( C ^ 48); C = GETCHAR();} 66 リターン F * X。 67 } 68 INT N。 69 LL [N]。 70 のint F [N]。 71 BT S [N]。 72 のint main()の 73 { 74 // freopenは( "buylow.in"、 "R"、標準入力)。 75 // freopenは( "buylow.out"、 "W"、STDOUT); 76 scanfの(" %のD "、およびN-); 77 用(INT I = 1 ; I <= N; I ++ ) 78 A [I] = RD(); 79 / * 80 統計答えバックは、すべて一緒にF [I] == max_long Sの[I]が 81 、その場所は、Sの外観を繰り返した場合、[]はゼロでなければならない 82 3 2 2 3 1 1。 83 S []の数が0であることをバック3 84 1つの回答に割り当てられた初期値が1間違っているかどう 85 * / 86 S [ 0 ] .INIT()、[ 0 ] = LONG_MAX; 87 以下のために(INT iが= 1 ; I <= N; I ++ ) 88 { 89 のために(INT J = I- 1、J> = 0 ; j-- ) 90 であれば([J]> [i])と 91 F [I] = MAX(F [I]、F [J] + 1 )。 92 のために(INT J = I- 1、J> = 0 ; j-- ) 93 { // 记录方案数 94 であれば([J]> [I] && F [I] == F [J] + 1)S [I] = S [I] + S [J]。 95 もし(A [I] == A [J] && F [I] == F [J])BREAK ; 96 / * 97が 重複防ぐ 98 。3 2 2 1 1 3 99 。3 2 1はい本質的に同一の配列 100が 防止することです6ときの第二の数への転送数 101 * / 102 } 103 } 104 LL T1 = 0 ; BT T2; 105 用(INT I = 1 ; I <= N; I ++ ) 106 { 107 IF(F [ I]> T1) 108 T1 = F [I]、T2 = S [I]; 109 そう IF(F [I] == T1)T2 = T2 + S [i]は、 110 } 111 のprintf(" %のLLD " 、T1)。 112 t2.write()。 113の プット("" ); 114 戻り 0 ; 115 }