Testing the CATCHER Uva231 最长递减子序列

A  military  contractor  for  the  Department  of  Defense  has  just  completed  a  series  of  preliminary  tests 
for  a  new  defensive  missile  called  the  CATCHER  which  is  capable  of  intercepting  multiple  incoming 
offensive  missiles.   The  CATCHER  is  supposed  to  be  a  remarkable  defensive  missile.           It  can  move 
forward, laterally, and downward at very fast speeds, and it can intercept an offensive missile without 
being damaged.  But it does have one major flaw.  Although it can be fired to reach any initial elevation, 
it has no power to move higher than the last missile that it has intercepted. 


    The  tests  which  the  contractor  completed  were  computer  simulations  of  battlefield  and  hostile 
attack  conditions.    Since  they  were  only  preliminary,    the  simulations  tested  only  the  CATCHER’s 
vertical movement capability.      In each simulation, the CATCHER was fired at a sequence of offensive 
missiles which were incoming at fixed time intervals.  The only information available to the CATCHER 
for each incoming missile was its height at the point it could be intercepted and where it appeared in 
the sequence of missiles.  Each incoming missile for a test run is represented in the sequence only once. 


    The  result  of  each  test  is  reported  as  the  sequence  of  incoming  missiles  and  the  total  number  of 
those missiles that are intercepted by the CATCHER in that test. 


    The General Accounting Office wants to be sure that the simulation test results submitted by the 
military contractor are attainable, given the constraints of the CATCHER. You must write a program 
that takes input data representing the pattern of incoming missiles for several different tests and outputs 
the maximum numbers of missiles that the CATCHER can intercept for those tests.  For any incoming 
missile  in  a  test, the  CATCHER  is  able  to  intercept  it  if  and  only  if  it  satisfies  one  of  these  two 
conditions: 


   1.  The incoming missile is the first missile to be intercepted in this test. 


 - or- 


   2.  The missile was fired after the last missile that was intercepted and it is not higher than the last 
       missile which was intercepted. 


Input 


The  input  data  for  any  test  consists  of  a  sequence  of  one  or  more  non-negative  integers,  all  of  which 
are  less  than  or  equal  to  32,767,  representing  the  heights  of  the  incoming  missiles  (the  test  pattern). 
The last number in each sequence is  -1, which signifies the end of data for that particular test and is 
not considered to represent a missile height.  The end of data for the entire input is the number  -1 as 
the first value in a test; it is not considered to be a separate test. 


Output 


Output  for  each  test  consists  of  a  test  number  (Test  #1, Test    #2,  etc.) and  the  maximum  number 
of  incoming  missiles  that  the  CATCHER  could  possibly  intercept for  the  test.      That  maximum num- 
ber  appears  after  an  identifying  message.   There  must  be  at  least  one  blank  line  between  output  for 
successive data sets. 


Note:  The number of missiles for any given test is not limited.  If your solution is based on an inefficient 
algorithm, it may  not execute in the allotted time. 


Sample Input 


389 
207 
155 
300 
299 
170 
158 
65 
-1 
23 
34 
21 
-1 
-1 


Sample Output 


Test   #1: 
   maximum    possible    interceptions:       6 


Test   #2: 

   maximum    possible    interceptions:       2 


题目大意:求一组数的最长递减子序列

思路:使用动态规划的方法,递推方程为

解释一下,dp[i]表示以i为结尾的最长递减子序列的长度,那么dp[0]=1,对于其他的i,dp[i]最小的长度为1,即自己成为一个序列,或者与前面最长的序列共同组成为一个序列,因此需要双重循环,算法复杂度O(n^2)。

另外,也可以转换为LCS(最长公共子序列)的问题,只需要对原序列进行排序,在将其与原序列求最长公共子序列即可,复杂度仍然为O(n^2)。


#include <iostream>
#include <stdio.h>
#define MAX 1010
using namespace std;


int get_res(int *data,int num)
{
    int dp[MAX],mx;
    dp[0]=1;
    for(int i=1;i<num;i++)
    {
        dp[i]=1;
        for(int j=i-1;j>=0;j--)
        {
            if(data[j]>data[i]&&dp[i]<dp[j]+1)
                dp[i]=dp[j]+1;
        }
    }
    mx=dp[0];
    for(int i=1;i<num;i++)
    {
        if(dp[i]>mx)
            mx=dp[i];
    }
    return mx;
}


int main()
{
    int h,data[MAX],i,cas=0;
    while(scanf("%d",&h))
    {
        if(h==-1)
            break;
        data[0]=h;
        i=1;
        while(scanf("%d",&h)&&h!=-1)
        {
            data[i++]=h;
        }
        if(cas!=0)
            printf("\n");
        printf("Test #%d:\n  maximum possible interceptions: %d\n",++cas,get_res(data,i));
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值