ACM: 最长升序和最长降序 dp题 poj…

来源:互联网 发布:深圳阿里云大厦 编辑:程序博客网 时间:2024/06/10 19:28

                                                        Alignment

Description

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

Write a program that, knowing the height ofeach soldier, determines the minimum number of soldiers which haveto get out of line.

Input

On the first line of the input is written thenumber of the soldiers n. On the second line is written a series ofn floating numbers with at most 5 digits precision and separated bya space character. The k-th number from this line represents theheight 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 thenumber 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

 

题意: 士兵站队列.要求至少的多少个出队列满足当前第i个士兵可以看到全部左边的队友或则全部右边的队友.

 

解题思路:

               1. 模型还是挺熟悉的. 最长升序和最长降序. dp问题.

               2. 设dp1[i]表示当前第i个前序中,最大的满足升序元素个数.

                     dp2[i]表示当前第i个以后直到序列结束,最大的满足降序元数个数.

               3. 最后将两个dp1 , dp2集合合并寻找出最大的子集序列, 同时满足最大升序或则最大将序.

                   合并证明就自己理解咯.不证明. 结果n - merge(e); 就是最少出队个数.

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define MAX 1005

int n;
double a[MAX];
int dp1[MAX];
int dp2[MAX];

int main()
{
//   freopen("input.txt","r",stdin);
   while(scanf("%d",&n) !=EOF)
   {
      for(int i = 1; i <= n;++i)
         scanf("%lf",&a[i]);
      memset(dp1,0,sizeof(dp1));
      memset(dp2,0,sizeof(dp2));
      
      dp1[1] = 1;
      for(int i = 2; i <= n;++i)
      {
         dp1[i] = 1;
         for(int j = i-1; j >= 1;--j)
         {
            if(a[i] > a[j]&& dp1[i] <dp1[j]+1)
            {
               dp1[i] = dp1[j]+1;
            }
         }
      }
      
      dp2[n] = 1;
      for(int i = n; i >= 1;--i)
      {
         dp2[i] = 1;
         for(int j = i+1; j <= n;++j)
         {
            if(a[i] > a[j]&& dp2[i] <dp2[j]+1)
            {
               dp2[i] = dp2[j]+1;
            }
         }
      }
      
      int ans = dp1[n];
      for(int i = 1; i < n;++i)
      {
         for(int j = i+1; j <= n;++j)
         {
            if(ans < dp1[i] +dp2[j])
               ans = dp1[i]+dp2[j];
         }
      }
      printf("%d\n",n-ans);
   }
   return 0;
}

0 0
原创粉丝点击