怪盜基德的滑翔翼


怪盜基德的滑翔翼

怪盜基德是一個充滿傳奇色彩的怪盜,專門以珠寶爲目標的超級盜竊犯。而他最爲突出的地方,就是他每次都能逃脫中村警部的重重圍堵,而這也很大程度上是多虧了他隨身攜帶的便於操作的滑翔翼。

這裏寫圖片描述

有一天,怪盜基德像往常一樣偷走了一顆珍貴的鑽石,不料卻被柯南小朋友識破了僞裝,而他的滑翔翼的動力裝置也被柯南踢出的足球破壞了。不得已,怪盜基德只能操作受損的滑翔翼逃脫。
假設城市中一共有N幢建築排成一條線,每幢建築的高度各不相同。初始時,怪盜基德可以在任何一幢建築的頂端。他可以選擇一個方向逃跑,但是不能中途改變方向(因爲中森警部會在後面追擊)。因爲滑翔翼動力裝置受損,他只能往下滑行(即:只能從較高的建築滑翔到較低的建築)。他希望儘可能多地經過不同建築的頂部,這樣可以減緩下降時的衝擊力,減少受傷的可能性。請問,他最多可以經過多少幢不同建築的頂部(包含初始時的建築)?

Input

輸入數據第一行是一個整數K,代表有K組測試數據。
每組測試數據包含兩行:第一行是一個整數N,代表有N幢建築。第二行包含N個不同的整數,每一個對應一幢建築的高度h,按照建築的排列順序給出。

Output

對於每一組測試數據,輸出一行,包含一個整數,代表怪盜基德最多可以經過的建築數量。

Sample Input

3
8
300 207 155 299 298 170 158 65
8
65 158 170 298 299 155 207 300
10
2 1 3 4 5 6 7 8 9 10

Sample Output

6
6
9

Range

N < 100;
0 < h < 10000;
K < 100.

Analvsis

這一題其實是最長上生序列與最長下降序列的結合,需要求出最長上升序列的長度,與最小下降序列的長度,輸出較大的那一個。
(我第一次做的時候,就只求了最長下降序列並輸出,不幸答案錯誤%>_<%)
此爲其一,其二,此題有多組測試數據,所以每一次使用數組後,養成一個好習慣,把數組清零。
下面是清零函數及所需頭文件(一維,二維需要循環清零);
b[i](狀態)是表示從第i個開始最長的下降或上升序列;
h[i]表示第i個的高度
memset(b,0,sizeof(b));//#include<cstring>
memset(h,0,sizeof(h));

有了狀態,狀態轉移方程式就有了

b[i]=max(b[j]+1,b[i]);

於是 ·············································
就有了代碼的核心部分
1.求最長下降序列

for(int i=2;i<=k;i++)
            for(int j=1;j<i;j++)
                if(h[j]>h[i])
                        b[i]=max(b[j]+1,b[i]);

2.最長上升序列

for(int i=k-1;i>=1;i--)
            for(int j=k;j>i;j--)
                if(h[j]>h[i])
                        b[i]=max(b[j]+1,b[i]);

接下來,我們發現 (⊙o⊙)…
怎麼找到這個最長下降序列(上升序列)呀?
其實,只需要一個函數即可(或用循環枚舉每一個,找出最大的)

*max_element(b+1,b+k+1)+1;//b數組第1個下標開始到第k個數中,從中選出最大的數。

有了這些,代碼也可以實現了!!!

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int b[5005],h[5005];
int main()
{
    int p;
    scanf("%d",&p);
    for(int l=1;l<=p;l++)
    {
        memset(b,0,sizeof(b));
        memset(h,0,sizeof(h));
        int k;
        scanf("%d",&k);
        for(int q=1;q<=k;q++)
            scanf("%d",&h[q]);
        for(int i=2;i<=k;i++)
            for(int j=1;j<i;j++)
                if(h[j]>h[i])
                        b[i]=max(b[j]+1,b[i]);
        int s1=*max_element(b+1,b+k+1)+1;
        memset(b,0,sizeof(b));
        for(int i=k-1;i>=1;i--)
            for(int j=k;j>i;j--)
                if(h[j]>h[i])
                        b[i]=max(b[j]+1,b[i]);
        int s2=*max_element(b+1,b+k+1)+1;
        printf("%d\n",max(s1,s2));
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章