双方向POJ-1836-Alignment- LIS(立ち上がり最長シーケンス)(LIS + LSD)+ DP

軍隊では、小隊は、n兵士によって構成されています。朝の検査の際、兵士たちは船長の前に一直線に並んでいます。船長は彼の兵士が整列されている方法に満足していません。、1、2、3:兵士が彼らのコード番号順に並んでいることは事実です。、nは、しかし、彼らは、その高さで整列されていません。船長は、各兵士の少なくとも1行縦に見ることによって見ることができる新しいラインを形成するために、その場所を変更することが、近づいてなくて、ラインに残っている兵士として、ラインから抜け出すために、いくつかの兵士を尋ねますラインの四肢(左または右)。彼とその先端の間に彼の高さ以上と高さのいずれかの兵士がない場合、兵士が四肢を参照してください。 

各兵士の高さを知って、プログラムを書く、ラインの外に取得する必要が兵士の最小数を決定します。 

入力

入力の最初の行にN兵士の数を書き込まれます。二行目に最大で5桁の精度でNフローティング一連の数字を書き込まれ、空白文字で区切られました。このラインからk番目の数は、コードK(1 <= K <= N)を有している兵士の高さを表しています。 

いくつかの制限があります。 
•2 <= N <= 1000 
•高さは[0.5、2.5]間隔から番号を浮遊しています 

出力

出力の唯一のラインはラインの外に取得する必要が兵士の数が含まれています。

サンプル入力

8
 1.86 1.86 1.30621 2 1.4 1 1.97 2.2

サンプル出力

4 

質問の意味:
  兵士の高さ(繰り返します)、あなたは兵士たちを見るためにキューの最後を見ることができ、各兵士は、左または右のように兵士を得るために、最低限の要件を除く与えられ、元の位置が変化しない場合があります。
  

注意:
  1. ソートを直接変更しない要求キュー順序の元の件名ので、最高の兵士が要素の重複を除く外に除去することはできません。
  2. 彼とその先端の間に彼の高さ以上と高さのいずれかの兵士がない場合兵士は四肢を参照してください。それは他よりも最高の繰り返しの高さを有していても良い兵士に加えて、で取得するには、キュー内の最後であります兵士の高さは、重複することはできません。それは極端なの最大値であります

 

アイデア: 

  NUM [i]の要素のいずれかを取り、番号num [n]を削除するために必要な必要最小限の数に相当し、満足1.num [0]〜NUM [i]は単調増加; 2.num [I ]〜NUM [N-1]単調に減少します。それは極端なまでです。

  LIS LDSを得る(後方必要スイープ)、そして最後にキュー列挙位置の頭に尾部、及びANS = N-MAXから(DP1 [ I] + DP2 [I])。

 

 元のデータ:1 1.86 1.86 1.4 1.97 2 2.2 1.30621 
 最長シーケンス上昇:1.86
         1.30621 2
        1.30621 1.4(1.4失われた2位を置換するために)
         1 1.4 1.97 2.2(より好ましくは1〜1.30621に、1.30621の位置を交換します後者のデータは、(最終的なシーケンスは、最長長さによって得られる)を更新する必要はないが、最大長さが得られ、同じ長さの正しい順序)
        、この長さは、上記のように(1.30621 1.4 1.97 2.2)(データ長の組として、この長さは正しくソートされている)
         最長長さ:4
 最長シーケンスドロップ:1.86 1.30621
         2 1.30621
         2 1.4
         2 1.4 1
         2 1 1.97
         2.2 1.97 1
         (1.86 1.30621 1; 1.86 1.4 1; 2 1.4 1)
         最大長さ:3
:なおより良いと、最長だけ上昇または下降系列長を求め、必ずしもそうではない要素内部が正しく昇順または降順に配置されていますデータは元のデータの位置を交換します。)

問題の時間計算のための質問:書き込みの2種類の最長シーケンス、通常の書き込みO(N-ためにそこに上昇している2)、O(nlogn)の文言と恐れるタイムアウトかもしれません。


 

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7 
 8 float a[1010];
 9 int dpup[1010];
10 int dpdown[1010];
11 
12 int main()
13 {
14     std::ios::sync_with_stdio(false);
15     int n;
16     cin>>n;
17     memset(dpup,0,sizeof(dpup));
18     memset(dpdown,0,sizeof(dpdown));
19     for(int i=0; i<n; i++)
20         cin>>a[i];
21     for(int i=0; i<n; i++)
22     {
23         dpup[i]=1;
24         for(int j=0; j<i; j++)
25         {
26             if(a[j]<a[i])
27             {
28                 dpup[i]=max(dpup[i],dpup[j]+1);
29             }
30         }
31     }
32 //
33 //    for(int i=0; i<n; i++)
34 //    {
35 //        dpdown[i]=1;
36 //        for(int j=0; j<i; j++)
37 //        {
38 //            if(a[j]>a[i])
39 //            {
40 //                dpdown[i]=max(dpdown[i],dpdown[j]+1);
41 //            }
42 //        }
43 //    }
44 
45     for(int i=n-1; i>=0; i--) //这里需要倒着扫
46     {
47         dpdown[i]=1;
48         for(int j=n-1; j>i; j--)
49         {
50             if(a[i]>a[j])
51                 dpdown[i]=max(dpdown[j]+1,dpdown[i]);
52         }
53     }
54     int ans=-inf;
55     for(int i=0; i<n; i++)
56     {
57         for(int j=i+1; j<n; j++)
58         {
59             //      if(a[i]==a[j])
60             //         ans=max(ans,dpup[i]+dpdown[j]-1);
61             //      else
62             ans=max(ans,dpup[i]+dpdown[j]);
63         }
64     }
65     cout<<n-ans<<endl;
66     return 0;
67 }
View Code

 

 

 

  

  

おすすめ

転載: www.cnblogs.com/OFSHK/p/11220951.html