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 */

 

posted @ 2012-08-27 11:54  pushing my way  阅读(399)  评论(0编辑  收藏  举报