攔截導彈

問題描述:

某國爲了防禦敵國的導彈襲擊,發展出一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠達到任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的導彈來襲。由於該系統還在使用階段,所以只有一套系統,因此有可能不能攔截所有的導彈。

輸入導彈依次飛來的高度(雷達給出高度數據是不大於30000的正整數),計算這套系統最多能攔截多少導彈,如果要攔截所有導彈最少要配備多少套這種導彈系統。

樣例:

 Input: 389 207  155  300  299  170  158  65

Output: 6(最多攔截導彈數)

        2(要攔截所有導彈最少要配備的系統數)

運行示例:

INPUT: 300 250 275 252 200 138 245

OUTPUT: 5 2

INPUT: 181 205 471 782 1033 1058 1111

OUTPUT: 1 7

INPUT: 465 978 486 324 575 384 278 214 657 218 445 123

OUTPUT: 6 4

INPUT: 236 865 858 565 545 445 455 656 844 735 638 652 569 714 845

OUTPUT: 6 7

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

問題分析

  第一問可以抽象爲,求一組數列的最長降序列。設st(n)爲數組中以第n個數爲頭的最長遞減序列長度。st(n-1)=max(st(x1),st(x2)...st(xi))+1. 其中n<=xi<=N,並且數組中第xi個數要小於第n-1個數。可以用遞歸。

  第二問:用鏈表存儲n個高度。先找鏈表中最大的數,並紀錄最大數的下一個位置t,刪除那個最大的數。再從t開始找最大的數,再紀錄再刪除。直到t爲表尾,結束一輪。系統數加1。再從表頭開始重複上一步,直到鏈表爲空。
例如:7 6 2 8 5 3
先找到8,刪除8。再從5開始找,5最大刪除。再從3開始,3爲表尾刪除,並結束一輪。
再從表頭7開始找,刪除762後表爲空。停止 系統即:8 5 37 6 2

第二問的算法可以用一個有向無環圖來證明。


數據結構

  第一問用數組存儲n個高度。程序中用high[]這個數組。

  第二問用帶頭結點的單鏈表來儲存n個數字。

typedef struct Node

{

    int val;

    struct Node *next;

}Node,*Link;

 

程序清單

#include <stdio.h>

#define N 100

int high[N+1]={0};

int k=0;

int system=0;

 

int NoMaxSq(int n)

{

    int i,max;

    if(n==k)

        return 1;

    else

    {

        max=0;

        for(i=n+1;i<=k;i++)

        {

            if(high[i]<high[n])

                max=NoMaxSq(i);

            break;

        }

        for(i=n+1;i<=k;i++)

        {

            if(high[i]<high[n])

                if(NoMaxSq(i)>max)

                    max=NoMaxSq(i);

        }

 

        return max+1;

 


    }

}

 

 

 

typedef struct Node

{

    int val;

    struct Node *next;

}Node,*Link;

 

Node *PriorElem(Link L,Node *t)

{ 

    Node *p=L;

    while((p!=0)&&(p->next!=t))

        p=p->next;

    return p;

}

 

 

void SystemNo()

{

    int i,max;

    Node *p,*t,*q;

    Node *mp,*temp;

    Link L;

    L=(Link) malloc(sizeof(Node));

    L->next=NULL;

    for(i=k;i>0;--i)

    {

        p=(Link)malloc(sizeof(Node));

        p->val=high[i];

        p->next=L->next;L->next=p;

    }

    do

    {

        t=L->next;

        do

        {

            q=PriorElem(L,t);

            for(max=t->val;t;q=t,t=t->next)

                if(max<=t->val)

                {

                   max=t->val;

                   temp=t;

                   mp=q; 

                }

            mp->next=temp->next;

            free(temp);

             t=mp->next;

        }while(t);

        ++system;

    }while(L->next);

 

 

}

 

 

main()

{

    void SystemNo();

 

    int i=0,n=0;

    int max;

    char c;

    char s[100];

    while((c=getchar())!='/n')

    {

        s[i++]=c;

    }

    s[i]='/0';

    i=0;

    while(s[i]!='/0')

    {

        if(s[i]==' ')

            i++;

        for(;s[i]>='0'&&s[i]<='9';++i)

            n=10*n+(s[i]-'0');

        high[++k]=n;

 

        n=0;

    }

    max=0;

 

    for(i=1;i<=k;i++)

        if(max<NoMaxSq(i))

            max=NoMaxSq(i);

    printf("%d",max);

    SystemNo();

    printf("      %d",system);

    getch();

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章