poj1836_双向lis

题意:令到原队列的最少士兵出列后,使得新队列任意一个士兵都能看到左边或者右边的无穷远处。

分析:

题意一开始没看明白,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.
可知求的是递增序列,然后形成的序列应该是这样的:
使剩下的队列满足a1 < a2 < a3 ... < a(i ) <=> a(i+1) > a(i+2) > .. a(n-1) > a(n)

双向lis后,在对所有的点遍历一遍即可。

代码:

View Code
 1 #include <iostream>

 2 #include <stdio.h>

 3 using namespace std;

 4 //180K 32MS

 5 //dp

 6 const int maxnum=1005;

 7 double a[maxnum];

 8 int dp[maxnum],Dp[maxnum];

 9 

10 int main()

11 {

12     int n,i,j;

13     scanf("%d",&n);

14     for(i=0;i<n;i++)

15     {

16         scanf("%lf",&a[i]);

17         dp[i]=1;

18         Dp[i]=1;

19     }

20     for(i=1;i<n;i++) //求正向递增序列

21         for(j=0;j<i;j++)

22             if(a[i]>a[j])

23                 dp[i]=max(dp[i],dp[j]+1);

24     for(i=n-2;i>=0;i-- )//求反向递增序列

25         for(j=n-1;j>i;j--)

26             if(a[i]>a[j])

27                 Dp[i]=max(Dp[i],Dp[j]+1);

28 

29     int ans=0;

30     for(i=0;i<n-1;i++)  //最后遍历一遍即可

31         for(j=i+1;j<n;j++)

32             ans=max(ans,dp[i]+Dp[j]);

33     printf("%d\n",n-ans);

34     return 0;

35 }

36 /*

37 8

38 3 4 5 1 2 5 4 3

39 6

40 4 2 3 5 4 3

41 */

 

你可能感兴趣的:(poj)