OpenJ_Bailian - 2945 攔截導彈(最長遞減子序列)

sunlanchang發表於2019-01-28

Description

某國為了防禦敵國的導彈襲擊,開發出一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的導彈來襲,並觀測到導彈依次飛來的高度,請計算這套系統最多能攔截多少導彈。攔截來襲導彈時,必須按來襲導彈襲擊的時間順序,不允許先攔截後面的導彈,再攔截前面的導彈。

Input

輸入有兩行,
第一行,輸入雷達捕捉到的敵國導彈的數量k(k<=25),
第二行,輸入k個正整數,表示k枚導彈的高度,按來襲導彈的襲擊時間順序給出,以空格分隔。

Output

輸出只有一行,包含一個整數,表示最多能攔截多少枚導彈。

Sample Input

8
300 207 155 300 299 170 158 65

Sample Output

6

Solution

最長遞減子序列(準確說應該是不增)。LIS模板修改即可。

  • 注意dp初始化為1。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 26;
int dp[maxn], arr[maxn];
void init()
{
    memset(dp, 0, sizeof(dp));
}
int main()
{
    // freopen("in.txt", "r", stdin);
    int N;
    while (~scanf("%d", &N))
    {
        init();
        dp[1] = 1;
        for (int i = 1; i <= N; i++)
        {
            scanf("%d", &arr[i]);
            //初始化要初始為1!!!!!!
            dp[i] = 1;
        }
        for (int i = 1; i <= N; ++i)
        {
            // 每次外部迴圈,確定以當前位置為末尾元素的最長子序列;
            for (int j = 1; j < i; ++j)
                // 通過遍歷 j 實現對 dp[i] 的更新
                if (arr[j] >= arr[i])
                    dp[i] = max(dp[i], 1 + dp[j]);
        }
        int ans = 0;
        for (int i = 1; i <= N; i++)
            ans = max(ans, dp[i]);
        printf("%d\n", ans);
    }
    return 0;
}

相關文章