POJ - 1836 Alignment (最長上升子序列 O(nlogn))


解題思路:是POJ2533的擴展題。

題意不難,令到原隊列的最少士兵出列後,使得新隊列任意一個士兵都能看到左邊或者右邊的無窮遠處。就是使新隊列呈三角形分佈就對了。

 

但這裏有一個陷阱,看了一些別人的解題報告說“任一士兵旁邊不能存在等高的士兵”,然後又舉了一個例子說注意

3

5 5 5

的情況,我沒看他們的程序,不知道他們是不是把這些例子特殊處理了,但完全沒必要,因爲“允許處於三角形頂部的兩個士兵等高”,圖形化就是如下圖:


 

其實藍色士兵的身高和紅色士兵的身高是完全沒有關係的。

 

要求最少出列數,就是留隊士兵人數最大,如圖,即左邊的遞增序列人數和右邊的遞減序列人數之和最大

因而可轉化爲求“最長不降子序列”和“最長不升子序列”問題



注意:等高的也會遮住視線!!!!


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double inf = 3.0;
int pre[1111],back[1111];
double dp[1111],a[1111];
void print(int n)
{
    int i;
    for(i=1;i<=n;i++) cout<<pre[i]<<" ";
    cout<<endl;
    for(i=1;i<=n;i++) cout<<back[i]<<" ";
    cout<<endl;
}
int main()
{
    int i,j,n,ans;
    int p1,p2,p;
    cin>>n;
    for(i=1;i<=n;i++) cin>>a[i];
    fill(dp,dp+n,inf);
    for(i=1;i<=n;i++) {
        p = lower_bound(dp,dp+n,a[i])-dp;
        dp[p] = a[i];
        pre[i] = max(pre[i-1],p+1);
    }
    fill(dp,dp+n,inf);
    ans=0;
    for(i=n;i;i--) {
        p = lower_bound(dp,dp+n,a[i])-dp;
        dp[p] = a[i];
        back[i] = max(back[i+1],p+1);
    }
  //  print(n);
    for(i=1;i<=n;i++) {
    	for(j=i+1;j<=n;j++) {
    		ans=max(ans,pre[i]+back[j]);
		}
	}

    cout<<n-ans<<endl;
    return 0;
}


In the army, a platoon is composed by n soldiers. During the morning inspection, the soldiers are aligned in a straight line in front of the captain. The captain is not satisfied with the way his soldiers are aligned; it is true that the soldiers are aligned in order by their code number: 1 , 2 , 3 , . . . , n , but they are not aligned by their height. The captain asks some soldiers to get out of the line, as the soldiers that remain in the line, without changing their places, but getting closer, to form a new line, where each soldier can see by looking lengthwise the line at least one of the line's extremity (left or right). A soldier see an extremity if there isn't any soldiers with a higher or equal height than his height between him and that extremity. 

Write a program that, knowing the height of each soldier, determines the minimum number of soldiers which have to get out of line. 
Input
On the first line of the input is written the number of the soldiers n. On the second line is written a series of n floating numbers with at most 5 digits precision and separated by a space character. The k-th number from this line represents the height of the soldier who has the code k (1 <= k <= n). 

There are some restrictions: 
• 2 <= n <= 1000 
• the height are floating numbers from the interval [0.5, 2.5] 
Output
The only line of output will contain the number of the soldiers who have to get out of the line.
Sample Input
8
1.86 1.86 1.30621 2 1.4 1 1.97 2.2
Sample Output
4




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章