POJ 1836 Alignment 【最长上升(下降)子序列】

来源:互联网 发布:软件行业会计核算 编辑:程序博客网 时间:2024/04/27 16:09

题目链接:http://poj.org/problem?id=1836

题目大意:对一排士兵重新排序,使新队列每个兵向左或向右都能看到左端或者右端,也就是使新队列的每个士兵的身高呈三角形分布即可。求出需要让最少多少个士兵能完成。

解法:此处借用小优博客的图说明这个问题,对士兵们进行遍历,使每个士兵作为下图的绿色柱子,下一个士兵作为红色柱子,然后每次循环求出绿色士兵之前最长上升子序列,以及红色士兵之后的最长下降子序列,士兵总人数减去这两个数之和,就得到了结果,然后在比较出最小的数就行了。

在这里,求最长上升子序列的方法如果用一般的方法,则复杂度为O(n^2),放在这里总的复杂度就成了O(n^3)对于这题来说一定超时了,所以只能用另一种复杂度为O(n*logn)的求法。关于这种算法的解释,参见:http://www.cnblogs.com/waytofall/archive/2012/09/10/2678576.html

代码:

#include <iostream>#include <cstdio>using namespace std;#define N 1001int n,ans,temp_ans1,temp_ans2;double temp;double h[N];double a[N];int B_Search_1(double a[],int head,int tail,double x){    int low=head,high = tail,mid;    while(low<=high)    {        mid = (low+high)/2;        if (a[mid]==x)return mid;        else if(a[mid]>x)high = mid-1;  //即中间值大于x,在下半段        else low = mid+1;               //中间值小于x,在上半段    }    return low;}int B_Search_2(double a[],int head,int tail,double x){    int low=head,high = tail,mid;    while(low<=high)    {        mid = (low+high)/2;        if (a[mid]==x)return mid;        else if(a[mid]<x)high = mid-1;  //即中间值大于x,在下半段        else low = mid+1;               //中间值小于x,在上半段    }    return low;}int main(){    scanf("%d",&n);    a[0]=-1;    for(int i=1;i<=n;i++)    {        scanf("%lf",&h[i]);        a[i]=3;                //设置为无穷大,    }    for(int i=1;i<=n;i++)    {        temp_ans1=0;        temp_ans2=0;        a[0]=-1;        for(int m=1;m<=n;m++)            a[m]=3;        for(int j=1;j<=i;j++)        {            int t=B_Search_1(a,0,i,h[j]);            if(a[t]==3)                temp_ans1++;            a[t]=h[j];        }        a[0]=3;        for(int m=1;m<=n;m++)            a[m]=-1;        for(int j=i+1;j<=n;j++)        {            int t=B_Search_2(a,i+1,n,h[j]);            if(a[t]==-1)                temp_ans2++;            a[t]=h[j];            //temp_ans2=max(temp_ans2,t)-1;        }        ans=max(ans,temp_ans1+temp_ans2);    }    printf("%d\n",n-ans);    return 0;}


0 0
原创粉丝点击