合計時間制限:メモリ制限を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;
}