羅区リンク:https://www.luogu.org/problem/P1020
タイトル説明
ミサイル迎撃システムを開発するために、敵のミサイル攻撃を防御するために国。任意の高さに到達するための最初のラウンドですが、しかし、各シェルと状況は高さを持って前よりも大きくすべきではない。しかし、そのようなミサイル迎撃システムは欠陥を持っています。ある日、レーダーは、入ってくる敵のミサイルを拾いました。システムとして、ベータまだそう唯一のシステムであるため、すべてのミサイルを迎撃しないことができます。
ミサイルターン浮上高さを入力します(レーダデータの高さが一定である\ル50000 ≤ 5 0 0 0は正の整数である)、あなたが設定し、この最小数の装備されるように、すべてのミサイルを迎撃する場合、ミサイルを迎撃するためにどのくらいのシステムアップ計算ミサイル迎撃の一種。
入力形式
1 一行、整数の複数(数\ 100000ル≤ 。1 0 0 0 0 0)
出力フォーマット
2つの2行は、それぞれが整数行目、最初の数がミサイルを迎撃するためにどのくらいのシステムアップを示しているすべてのミサイルに、このようなミサイル迎撃システムを搭載するセットの最小数を傍受したい場合は、2番目の数字は示しています。
サンプル入力と出力
389 207 155 300 299 170 158 65
6 2
説明/ヒント
あなたがより良いテストのnアルゴリズム、この質問オープンSPJを与え、nは100、nlogn200ポイントを側に
私は尋ねたサブによると、すべての2点を尋ねました
問題の解決策
この質問は基本的に今あるDP問題のエントリです。
最初の質問を探していることは最も長いシーケンスを落下し、実際にではなく、2番目の質問を求めている最長のシーケンスを増加させました。
最も容易に理解O(N 2溶液)、およびO(nlogn)不可解なのいくつかを解決します。最もユーザーフレンドリーで書かれた原則のこの部分はあるa342374071記事:https://blog.csdn.net/a342374071/article/details/6694452。
第1ペーストO(N-次の2)コード。
1の#include <iostreamの> 2の#include <stdio.hの> 3の#include <math.h>の 4の#include <アルゴリズム> 5の#include < 文字列・H> 6 7 使って 名前空間STDを、 8 9 のconst int型 MAXN = 1E5 + 10 。 10 INTはn = 1 、[MAXN]、D [MAXN]、DP [MAXN]。 11 12 のint main()の 13 { 14 INT ANS1 = 0、ANS2 = 0 。 15 一方(scanf関数(" %のD "、および[N])!= EOF) 16 { 17 ++ N。 18 } 19 - N。 20 のためには、(int型 i = 1 ; iがn = <; iは++ ) 21 { 22 D [I] = 1 。 23 のための(int型、J = 1、J <I、J ++ ) 24 { 25が あれば([j]が> = [I]) 26 { 27 dは[I] = MAX(D [i]は、D [J] +1 ); 28 } 29 } 30 であれば(ANS1 < D [I]) 31 { 32 ANS1 = Dの[I]。 33 } 34 } 35 のための(int型 i = 1 ; iがn = <; iは++ ) 36 { 37 DP [I] = 1 。 38 のために(INT J = 1 ; J <I J ++ ) 39 { 40 であれば([J] < [i])と 41 { 42 DP [I] = MAX(DP [I]、DP [J] + 1 )。 43 } 44 } 45 であれば(ANS2 < DP [I]) 46 { 47 ANS2 = DP [I]。 48 } 49 } 50 COUT << ANS1 << ENDL。 51 COUT << ANS2 << ENDL。 52 リターン 0 。 53 }
以下は、O(nlogn)コードです。
1の#include <iostreamの> 2の#include <stdio.hの> 3の#include <math.h>の 4の#include <アルゴリズム> 5の#include < 文字列・H> 6 7 使って 名前空間STDを、 8 9 のconst int型 MAXN = 1E5 + 10 。 10 INTはn = 1、[MAXN]、D [MAXN]、DP [MAXN]、ANS1 = 0、ANS2 = 0 、MID、L、R。 11 12 のint main()の 13 { 14 ながら(scanf関数(" %dの"&[N])!= EOF) 15 { 16 ++ N; 17 続ける; 18 } 19 - N、 20 dが[ 1 ] [= 1 ;] 21 DP [ 1 ] [= 1 ]。 22 ANS1 = ANS2 = 1 ; 23 のための(int型 I = 2 ; iが<= N; iが++ ) 24 { 25 であれば([I] <= D [ANS1]) 26 { 27 ANS1 ++ ; 28 D [ANS1] = [I]を、 29 } 30 他の 31 { 32 、L = 1、R = ANS1。 33 一方(L < R) 34 { 35 半ば=(L + R)/ 2 。 36 であれば([I]> D [中間]) 37 { 38 = R ミッド。 39 } 40 他の 41 { 42 L =ミッド+ 1 。 43 } 44 } 45 D [L]は= [I]。 46 } 47 } 48 49 のために(int型 I = 2、I '= N; iが++ ) 50 { 51 であれば([I]> DP [ANS2]) 52 { 53 ANS2 ++ 。 54 DP [ANS2] = [I]を、 55 } 56 他の 57 { 58 L = 1、R = ANS2。 59 一方(L < R) 60 { 61 半ば=(L + R)/ 2 。 62 であれば([I] <= DP [中間]) 63 { 64 = R ミッド。 65 } 66 他の 67 { 68 、L =ミッド+ 1 。 69 } 70 } 71 DP [L]は= [I]を、 72 } 73 } 74 COUT << ANS1 << ENDL。 75 COUT << ANS2 << ENDL。 76 リターン 0 ; 77 }
このコードは、詳細は注意を払う必要があり、あること、ときの条件は、または他の内部の中に等号の上に置かれるべきであるならば、バイナリ検索。例えば、配列を求める場合には上昇しない、それは[i]とD [中間]が等しいことが望ましいので、右側にD [中間]を行うことができ、右側の[i]を置換データD [中間]、することが望ましいですデータ列が長くなるように、できるだけ大きく。過失がWAにつながることができますのであれば2つの比較条件内のプログラムは、非常に重要です。