Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。Input
输入描述:
一行,为导弹依次飞来的高度
输入样例:
389 207 155 300 299 170 158 65Output
输出描述:
两行,分别是最多能拦截的导弹数与要拦截所有导弹最少要配备的系统数
输出样例:
6
2
算法思想:
其实就是求最长的递减序列和最长的递增序列
主要的代码是sum=max(sum,L(j,len)+1)
每次sum的取值要么是已经确定的最长子序列,要么就是以a[j]开始的子序列同时还要加1(加的是i这个点)
#include<iostream>
#include<stdio.h>
using namespace std;
int a[100]={0};
int memo[100]={0}; //减少时间复杂度
int memo1[100]={0}; //减少时间复杂度
int max(int a,int b)
{
return a>b?a:b;
}
int L(int i,int len) //求数列以a[i]开始的最长的递增子序列元素数量
{
if(memo[i]!=0)
return memo[i];
int sum=1;
if(i==len-1)
return 1;
else
{
for(int j=i+1;j<len;j++)
{
if(a[j]<a[i])
{
sum=max(sum,L(j,len)+1);
}
}
memo[i]=sum;
return sum;
}
}
int L1(int i,int len) //求数列以a[i]的最长递减子序列元素数量
{
int cnt=1;
if(memo1[i]!=0)
return memo1[i];
if(i==len-1)
return 1;
else
{
for(int j=i+1;j<len;j++)
{
if(a[j]>a[i])
{
cnt=max(cnt,L1(j,len)+1);
}
}
memo1[i]=cnt;
return cnt;
}
}
int main()
{
int x;
int len=0;
int sum;
int cnt;
while(cin>>x)
{
a[len++]=x;
if(cin.get()=='\n')
break;
}
int max=L(0,len);
int min=L1(0,len);
for(int i=1;i<len;i++) //从该数列所有的子序列里面找最长的
{
if(L(i,len)>max)
max=L(i,len);
if(L1(i,len)>min)
min=L1(i,len);
}
cout<<max<<endl;
cout<<min<<endl;
return 0;
}