描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。怎么办呢?请帮助计算一下最少需要多少套拦截系统?
输入
输入若干组数据(不超过100组),每组数据一行,分别为:导弹总个数(正整数,不超过1000),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
输出
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统。
样例输入
8 389 207 155 300 299 170 158 65
样例输出
2
解题思路
这道题本质上是取最长的递减子序列,然后利用Dilworth定理最少要配备的系统数。
首先对于最长的递减子序列,可以采用深度优先的搜索来获取,或者利用动态规划来计算,状态转移方程是:
其中,下标i表示的是以i为结尾的降序或者升序数列。
之后,利用Dilworth定理,要计算最少的降序子序列,统计最长非递减序列中的元素数目即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[1001],dp[1001];//dp[i]表示到第i个导弹有多少个不升子序列 4 int n; 5 int main() 6 { 7 while(cin>>n) 8 { 9 memset(dp,0,sizeof(dp)); 10 for(int i=1;i<=n;i++)cin>>a[i],dp[i] = 1; 11 dp[1] = 1; 12 for(int i=1;i<=n;i++) 13 { 14 for(int j=1;j<i;j++) 15 { 16 if(a[i]>a[j])dp[i] = max(dp[i],dp[j]+1); 17 } 18 19 } 20 int ans = -1; 21 for(int i=1;i<=n;i++)ans = max(ans,dp[i]); 22 cout<<ans<<endl; 23 } 24 return 0; 25 }