Missile
总提交 : 147 测试通过 : 45
比赛描述
Long , long ago ,country A invented a missile system to destroy the missiles from their enemy . That system can launch only one missile to destroy multiple missiles if the heights of all the missiles form a non-decrease sequence .
But recently , the scientists found that the system is not strong enough . So they invent another missile system . The new system can launch one single missile to destroy many more enemy missiles . Basically , the system can destroy the missile from near to far . When the system is begun , it chooses one enemy missile to destroy , and then destroys a missile whose height is lower and farther than the first missile . The third missile to destroy is higher and farther than the second missile … the odd missile to destroy is higher and farther than the previous one , and the even missile to destroy is lower and farther than the previous one .
Now , given you a list of the height of missiles from near to far , please find the most missiles that can be destroyed by one missile launched by the new system .
输入
The input contains multiple test cases .
In each test case , first line is an integer n ( 0<n<=1000 ) , which is the number of missiles to destroy . Then follows one line which contains n integers ( <=109 ) , the height of the missiles followed by distance .
The input is terminated by n = 0 .
输出
For each case , print the most missiles that can be destroyed in one line .
样例输入
4
5 3 2 4
3
1 1 1
0
样例输出
3
1
题目来源
NUPT ACM
题意:一种导弹系统,第一次集中第一个目标,下次击中一个比前一个高度小的目标,再下次击中一个比前面高度大的目标,以此循环,问最终能击毁的最大目标数。
分析:最长上升子序列的变形。最长上升子序列有一种解法:建立数组dp[i],表示以a[i]为末尾的元素的最长上升子序列的最大长度,即每次对每个元素遍历前面的元素 找出a[j]<a[i] j<i 中最大的dp[j] dp[j]=dp[i]+1。理解此法后能帮助理解这一题。该题每一个给出的高度都可以作为“高”目标击中,也可作为"低"目标击中,以da数组表示该数作为高目标被击中时的最大目标数,db数组表示作为低目标击中时的最大目标数,当作为高目标击中的时候,从db数组中选择下标比它小且高度比它小的数,记作db[k],以k作为它的前面一个高度比它小的目标,此时da[i]=db[k]+1,找出所有的k得出最大的da[i]。同理可以得到如果如果a[i]的值小于a[k]则,此时i作为低点,更新db数组。最终遍历得到最大的值即为结果。见AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1005;
long long a[maxn];
int da[maxn],db[maxn];
int main()
{
<span style="white-space:pre"> </span>int n;
<span style="white-space:pre"> </span>while(~scanf("%d",&n),n)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for(int i=0; i<n; i++)
<span style="white-space:pre"> </span>scanf("%I64d",&a[i]);
<span style="white-space:pre"> </span>memset(da,0,sizeof(da));
<span style="white-space:pre"> </span>memset(db,0,sizeof(db));
<span style="white-space:pre"> </span>da[0]=1;//初始化
<span style="white-space:pre"> </span>db[0]=0;//初始化
<span style="white-space:pre"> </span>for(int i=0; i<n; i++)
<span style="white-space:pre"> </span>for(int j=0; j<i; j++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>if(a[j]<a[i])//如果i作为高点 前一个需要比它低
<span style="white-space:pre"> </span>da[i]=max(da[i],db[j]+1);
<span style="white-space:pre"> </span>if(a[j]>a[i])//如果i作为低点 前一个需要比它高
<span style="white-space:pre"> </span>db[i]=max(db[i],da[j]+1);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>int res=-1;
<span style="white-space:pre"> </span>for(int i=0; i<n; i++)
<span style="white-space:pre"> </span>res=max(res,max(da[i],db[i]));
<span style="white-space:pre"> </span>printf("%d\n",res);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return 0;
}
特记下,以备后日回顾。