导弹拦截
来源:互联网 发布:剑网3菊花插件dbm数据 编辑:程序博客网 时间:2024/05/18 03:49
A :导弹拦截
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹一次飞来的高度(雷达给出的高度不大于30000的正整数)。计算这套系统最多能拦截多少导弹。
输入
n颗依次飞来的导弹高度,导弹颗数<=1000。
输出
一套系统最多拦截的导弹数。
样例输入
7
300 250 275 252 200 138 245
样例输出
5
Solution
一道经典的求最长不上升子序列的题目
N^2做法:dp[i]表示以i结尾的最长子序列长度
则dp[i]=max{dp[j]+1}(1<=j<i && a[i]<=a[j])
Nlogn做法:
首先,我们要想一种能够加速寻找j的方法
我们用s[i]表示长度为i的子序列的最后一个元素的值的最大值
即 s[i]=max{a[j]}(dp[j]=i)
可以看出,s[]数组必定是不上升的
假设有 s[i]<s[j] 且 i<j
那么长度为j的子序列中的第i个元素的值d[i]>=d[j]=s[j]>s[i]
这与s数组的定义矛盾,
也就是说,s[i]的值应该是d[i],所以,s[j]必定<=s[i]
所以就可以二分,每次在s数组中找出
最后一个大于等于a[i]的值在s数组中的位置j
则dp[i]=j+1; s[j+1]=a[i];
CODE
CODE#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int maxn=1010;int dp[maxn],s[maxn],a[maxn];int n,ans;int my_binary_search(int l,int r,const int &key){int mid,ans=l-1;while (l<=r){mid=(l+r)>>1;if (s[mid]<key) r=mid-1;else {ans=mid; l=mid+1;}}return ans;}int main(){cin>>n;for (int i=1;i<=n;i++)cin>>a[i];dp[0]=0; dp[1]=1; s[1]=a[1]; ans=1;for (int i=2;i<=n;i++){int j=my_binary_search(1,ans,a[i]);dp[i]=j+1; s[j+1]=a[i];if (j+1>ans) ans=j+1;}cout<<ans;return 0; }
阅读全文
0 0
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 导弹拦截
- 导弹拦截
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 拦截导弹
- 【DM】设计模式总括-原则篇
- @Autowired注解的使用
- arcgis for javascript 绘制多边形
- Python 处理图像水印
- v-on
- 导弹拦截
- js小程序
- Servlet&JSP 第一章 Web应用程序简介
- shader学习基础之四(语法规范以及光照模型)
- 快速幂
- POJ 2449 Remmarguts' Date 求k短路 A*+dijkstra
- LeetCode第四题--求两个排序好的数组的中位数
- 查找-二分查找法-数据结构(25)
- Linux基础(一)