洛谷1020拦截导弹(NOIP1999)
http://www.sakurasake.icoc.me/nd.jsp?id=2#_np=2_327
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式:
一行,若干个正整数最多100个。
输出格式:
2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
输入样例#1:
389 207 155 300 299 170 158 65
输出样例#1:
6 2
分析:
第一问和T1差不多,第二问是个难点,最简单的办法是使用定理:一个序列中不上升子序列的最小覆盖数等于子序列中最长上升序列的长度
#include<bits/stdc++.h>
using namespace std;
int n=1,ans1=0,ans2=0;
intf[10005]={0},g[10005]={0},a[10005];
int main()
{
while(scanf("%d",&a[n])!=EOF)n++;
n--;
for(int i=1;i<=n;i++)
{
f[i]=1;g[i]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
if(a[j]>a[i])f[i]=max(f[i],f[j]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
if(a[j]<a[i])g[i]=max(g[i],g[j]+1);
for(int i=1;i<=n;i++)
{
if(f[i]>ans1)ans1=f[i];
if(g[i]>ans2)ans2=g[i];
// printf("%d%d\n",f[i],g[i]);
}
cout<<ans1<<endl;
cout<<ans2<<endl;
return 0;
}