1. 程式人生 > >hdu 1257(從最長下降子序列求解轉化為最長上升子序列求解)

hdu 1257(從最長下降子序列求解轉化為最長上升子序列求解)

某國為了防禦敵國的導彈襲擊,發展出一種導彈攔截系統.但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能超過前一發的高度.某天,雷達捕捉到敵國的導彈來襲.由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的導彈.
怎麼辦呢?多搞幾套系統唄!你說說倒蠻容易,成本呢?成本是個大問題啊.所以俺就到這裡來求救了,請幫助計算一下最少需要多少套攔截系統.
Input輸入若干組資料.每組資料包括:導彈總個數(正整數),導彈依此飛來的高度(雷達給出的高度資料是不大於30000的正整數,用空格分隔)
Output對應每組資料輸出攔截所有導彈最少要配備多少套這種導彈攔截系統.
Sample Input
8 389 207 155 300 299 170 158 65
Sample Output
2
這道題一看知道是動態規劃求LIS,我想的是挨個求最長下降子序列,然後一個個刪除。這種方法讓我卡在瞭如何去記錄路徑。菜菜的我只知道咋求長度,不知道如何求路徑。當時比賽的時候,我應該想把問題轉化。最長下降不就是求最長上升嗎,每上上升一次不久要新部署一個新導彈系統嗎?不久相當於求最長下降子序列,每次求得的序列第一個元素嗎,。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

int a[11000];
int dp[11000];
int main()
{
   int n;
   while(scanf("%d", &n) != EOF)
  {
        memset(a, 0, sizeof(a));
        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n; i ++)
            scanf("%d", &a[i]);
            int res = 0;
        for(int i = 1; i <= n; i ++)
        {
            dp[i] = 1;
            for(int j = 1; j < i; j ++)
            {
                if(a[j] < a[i])
                {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
                res = max(res, dp[i]);
            }
        }
        printf("%d\n", res);
  }
    return 0;
}