POJ 1836 Alignment LIS变形(最长上升子序列)

来源:互联网 发布:淘宝上iphone se 编辑:程序博客网 时间:2024/04/27 19:48

POJ 1836 Alignment    LIS变形(最长上升子序列)

题意:给 n 个数然后 让你求至少删除多少个数使剩下的数可以满足在自己的位子上可以看到最左边或最右边的人 看到最边上人 的条件是某一边上的人都比自己矮 思路: 这道题是 LIS 的变形只需要求出 在每个位置上的 左边的最长上升子序列个数 加上 右边的最长下降子序列的个数   最后 n - 去他们就可以了#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define expusing namespace std;int bsearch(int low,int high,double x,double a[]){    while(high>=low)    {        int mid=(high+low)/2;        if(a[mid]==x)        return mid;        else if(a[mid]<x)            low=mid+1;        else            high=mid-1;    }    return low;}double a[1100];int ilen[1100];double len[1100];int dlen[1100];int main(){    int n;    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)            scanf("%lf",&a[i]);        int ilenth=1;        len[1]=a[1];        ilen[1]=1;        for(int i=2;i<=n;i++)        {            if(len[ilenth]<a[i])                len[++ilenth]=a[i];            else            {                int flag=bsearch(1,ilenth,a[i],len);                len[flag]=a[i];            }            ilen[i]=ilenth;        }        int dlenth=1;        len[1]=a[n];        dlen[n]=1;        for(int i=n-1;i>=1;i--)        {            if(len[dlenth]<a[i])                len[++dlenth]=a[i];            else            {                int flag=bsearch(1,dlenth,a[i],len);                len[flag]=a[i];            }            dlen[i]=dlenth;        }        int Max=-1;        ilen[0]=0;        for(int i=1;i<=n;i++)        {            Max=max(Max,dlen[i]+ilen[i-1]);        }        printf("%d\n",n-Max);    }    return 0;}


1 0
原创粉丝点击