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