DPリニアNOI 8780迎撃ミサイル

合計時間制限:メモリ制限を1000ミリ秒:65536kBは
説明し
、敵のミサイル攻撃を防御するために、国をミサイル迎撃システムを開発します。任意の高さに到達するための最初のラウンドですが、しかし、各シェルと状況は高さを持って前よりも大きくすべきではない。しかし、そのようなミサイル迎撃システムは欠陥を持っています。ある日、レーダーは、入ってくる敵のミサイルを拾いました。システムは、ベータまだそう唯一のシステムであるため、すべてのミサイルを迎撃しないことがあります。よう

高さ(与えられたレーダデータの高30,000以上の正の整数大きくない)、計算どのくらいのシステムインターセプトミサイルまでを飛んでミサイルターンを入力します。

入力
最初の行の整数N(せいぜい15)であり、ミサイルの数を示します。
2行目は、順次ミサイル浮上量(所与のレーダデータの高さが30,000を超えない整数正である)、nは整数を含んでいます。

出力
アンインターセプトにミサイルまでの数を表す整数。

サンプル入力
8
389 207 155 30029917015865

サンプル出力
6

この質問は、線形DPタイトルの基礎であり、さらにはテンプレートタイトルトピックのこのタイプと考えられ、それについての書き込みは、後で参照をバックアップ。
タイトル自体は、難しいことではありません、後でシーケンスを立ち上がるだろうか求めて、最長の下落配列がコードにそう直接、問題のコードを取得するために使用されている最長の非需要のサブシーケンス、私は明確に十分に持っていると思いますコメントです。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <string.h>
const int MAX=1e6+5;
using namespace std;

int h[2000], d[2000], n, c;
int main()
{
  cin >> n;
  for (int i=0; i<n; i++)
    scanf("%d", &h[i]);
  d[0] = h[0];    /// d的第一个先记为第一个飞入的导弹
  c = 1;      /// 先设拦截下了第一颗
  int i, j;
  for (i=1; i<n; i++)   /// 从h的第1位开始遍历
  {
    for (j=c-1; j>=0; j--)  /// 从d中目前最优解c,-1的位置回溯
      if (h[i]<=d[j])     /// 找到d中>=h[i]的位置就跳出
        break;
    d[j+1] = h[i];/// 在d回溯过程中第一个>=h[i]的位置后换上h[i]
    if (j==c-1) c ++;/// 如果回溯过程是第一次就直接跳出了,证明当前导弹直接满
                     ///足上一个状态最长子序列的排列,所以它相当于直接接续在
                     ///上一状态最长子序列的后面,使其+1成为当前最长子序列
  }
/// 实在理解不了咱再模拟一手案例,结合一下代码就很好理解为什么最后输出c了
///389 207 155 300 299 170 158 65   c=1
///389 0   0   0   0   0   0   0    c=1
///389 207 0   0   0   0   0   0    c=2
///389 207 155 0   0   0   0   0    c=3
///389 300 155                      c=3
///389 300 299                      c=3
///389 300 299 170                  c=4
///389 300 299 170 158              c=5
///389 300 299 170 158 65           c=6
  
  cout << c << endl;
}
公開された19元の記事 ウォンの賞賛0 ビュー500

おすすめ

転載: blog.csdn.net/qq_43317133/article/details/99690719