1. 程式人生 > >最長上升子序列——蒜頭君的娃娃

最長上升子序列——蒜頭君的娃娃

計算 算法 ... 最大的 1.5 cst ng- one fix

蒜頭君十分喜愛它的娃娃,經常會把它們擺成一列。蒜頭君從左到右依次給他們編號為 11 到 NN,每個娃娃都有自己的萌值 T_iT?i??。現在蒜頭君想從已經擺好的隊列中,去除幾個娃娃,使得剩余的隊列滿足以下條件:

\displaystyle T_1 < ... < T_i > T_{i+1} > ... > T_K (1 \leq i \leq K)T?1??<...<T?i??>T?i+1??>...>T?K??(1iK)

現在已知隊列中 NN 個娃娃的萌值,請你幫蒜頭君計算一下,最少需要去除多少個娃娃才能滿足上面的條件。

輸入格式

輸入兩行。輸入第一行是一個整數 N(2 \leq N \leq 100)N(2N100),表示娃娃的總數。第二行輸入 NN 個整數,每兩個整數之間用一個空格隔開,第 ii 個整數 T_i(130 \leq T_i \leq 230)T?i??(130T?i??230) 是第 ii 個娃娃的萌值。

輸出格式

輸出一行,輸出一個整數,表示最少去除娃娃的個數。

樣例輸入

6
184 163 210 166 170 155

樣例輸出

2

分析:正向dp一次,反向dp一次,然後取兩次dp值的和中最大的那個。答案即為娃娃的總數減去最大和值+1。O(n^2)算法

AC代碼
技術分享
 1 #include <cstdio>
 2
#include <algorithm> 3 using namespace std; 4 int n;//娃娃總數 5 int a[105];//存儲娃娃萌值 6 int dp1[105];//存儲正向dp結果 7 int dp2[105];//存儲反向dp結果 8 void DP1()//正向dp 9 { 10 for(int i=1;i<=n;i++) 11 for(int j=1;j<i;j++) 12 { 13 if(a[i]>a[j]) 14 dp1[i]=max(dp1[i],dp1[j]+1
); 15 } 16 17 } 18 void DP2()//反向dp 19 { 20 for(int i=n;i>=1;i--) 21 for(int j=n;j>i;j--) 22 { 23 if(a[i]>a[j]) 24 dp2[i]=max(dp2[i],dp2[j]+1); 25 } 26 27 } 28 int get_ans() 29 { 30 int ans=0; 31 for(int i=1;i<=n;i++) 32 { 33 ans=max(ans,dp1[i]+dp2[i]); 34 } 35 return ans; 36 } 37 int main() 38 { 39 scanf("%d",&n); 40 for(int i=1;i<=n;i++) 41 { 42 scanf("%d",&a[i]); 43 dp1[i]=1; 44 dp2[i]=1; 45 } 46 DP1(); 47 DP2(); 48 int ans=get_ans(); 49 printf("%d\n",n-ans+1); 50 return 0; 51 }
View Code

 

最長上升子序列——蒜頭君的娃娃