NOI 8780 interceptor missile linear dp

Total time limit: 1000ms Memory Limit: 65536kB
describe
a country in order to defend against enemy missile attacks, to develop a missile interception system. But such a missile interceptor system has a flaw: Although it's the first rounds to reach any height, but each shell and should not be higher than before the situation got height. One day, the radar picked up incoming enemy missiles. As the system is still in beta, so only a system, and therefore may not intercept all the missiles.

Enter the missile turn flying height (height of the radar data given is not a positive integer greater than 30,000), calculate how much the system up to intercept missiles.

Input
of the first line is an integer N (no more than 15), indicates the number of missiles.
The second line contains N integers, sequentially missile flying height (the height of the radar data given is a positive integer no greater than 30,000).

Output
An integer representing the number of missile up to intercept.

Sample input
8
389 207 155 30029917015865

Sample output
6

This question is the basis of a linear dp title, and even considered this type of template title topic, write about it back later reference.
Title itself is not difficult, is the longest non-rising demand subsequence, seeking what would later rise up sequence, the longest decline sequences are used to get the code of the problem, so directly on the code, the comment I would like to have clear enough .

#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;
}
Published 19 original articles · won praise 0 · Views 500

Guess you like

Origin blog.csdn.net/qq_43317133/article/details/99690719