BIT寒假练习-2013__1012:导弹防御问题

来源:互联网 发布:苹果手机4g网络怎么开 编辑:程序博客网 时间:2024/05/17 23:58

经典DP。

最多一次可以拦截的导弹数,就是在数列中找到一个最长不上升子序列,需要多少防卫导弹就是求一个最长上升子序列。

up[i]表示以第i个为结尾的子序列中最长的不上升子序列的长度。up[i]=max{up[j] + 1}(h[j]>=h[i])。

down[i]表示以第i个为结尾的子序列中最长的上升子序列的长度。down[i]=max{down[j] + 1}(h[j]<h[i])。

一开始没有看出来需要多少防卫导弹就是求一个最长上升子序列,纠结了半天,看了别人的题解才明白的。有点水了,好歹以前还做过这题的,都忘了。。。

#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;int n,h[1100];int up[1100],down[1100];int main(){while (scanf("%d",&n) != EOF){      up[0] = -1;      down[0] = -1;      for (int i = 1 ; i <= n ; i ++)      {          scanf("%d",&h[i]);          up[i] = 1;          down[i] = 1;      }      for (int i = 1 ; i <= n ; i ++)      {          for (int j = 1 ; j < i ; j ++)          {              if (h[j] >= h[i]) up[i] = up[i]>up[j]+1 ? up[i] : up[j]+1;              if (h[j] < h[i]) down[i] = down[i]>down[j]+1 ? down[i] : down[j]+1;          }          up[0] = up[0]>up[i] ? up[0] : up[i];          down[0] = down[0]>down[i] ? down[0] : down[i];      }      printf("%d %d\n",up[0],down[0]);}}