程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1836 Alignment 最長遞增子序列(LIS)的變形,pojalignment

POJ 1836 Alignment 最長遞增子序列(LIS)的變形,pojalignment

編輯:C++入門知識

POJ 1836 Alignment 最長遞增子序列(LIS)的變形,pojalignment


大致題意:給出一隊士兵的身高,一開始不是按身高排序的。要求最少的人出列,使原序列的士兵的身高先遞增後遞減。

求遞增和遞減不難想到遞增子序列,要求最少的人出列,也就是原隊列的人要最多。

1 2 3 4 5 4 3 2 1

這個序列從左至右看前半部分是遞增,從右至左看前半部分也是遞增。所以我們先把從左只右和從右至左的LIS分別求出來。

如果結果是這樣的:

  A[i]={1.86 1.86 1.30621 2 1.4 1 1.97 2.2} //原隊列

  a[i]={1 1 1 2 2 1 3 4}

  b[i]={3 3 2 3 2 1 1 1}

如果是A[1]~A[i]遞增,A[i+1]~A[8]遞減。此時就是求:a[1]~a[i]之間的一個值與b[i+1]~b[8]之間的一個值的和的最大值。

O(n^2)和O(nlogn)算法都可以過。

O(n^2)算法:

#include <iostream>
#include <cstdio>
using namespace std;

const int Max=1e3+5;

int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    double a[Max]={0};
    for(int i=0; i<n; i++)
        scanf("%f",a+i);
    int l[Max]= {0},r[Max]= {0};
    l[0]=r[n-1]=1;
    for(int i = 1; i < n; i++)
    {
        int maxLen = 0;
        for(int j = 0; j < i; j++)
            if(a[j]<a[i])
                maxLen = max(maxLen,l[j]);
        l[i] = maxLen + 1;
    }
    for(int i=n-2; i>=0; i--)
    {
        int maxLen=0;
        for(int j=n-1; j>i; j--)
            if(a[j]<a[i])
                maxLen=max(maxLen,r[j]);
        r[i]=maxLen+1;
    }
    int maxlen=0;
    for(int i=0;i<n-1;i++)
        for(int j=i+1;j<n;j++)
            maxlen=max(maxlen,l[i]+r[j]);
    printf("%d\n",n-maxlen);
    return 0;
}

O(nlogn)算法

#include <iostream>
#include <cstdio>
using namespace std;

const int Max=1e3+5;
int l[Max]= {0},r[Max]= {0};
double B[Max];
int BinarySearch(double *a, double value, int n)
{
    int low = 0;
    int high = n - 1;
    while(low <= high)
    {
        int mid = (high + low) / 2;
        if(a[mid] == value)
            return mid;
        else if(value<a[mid])
            high = mid - 1;
        else
            low = mid + 1;
    }
    return low;
}
int LIS_DP_NlogN(double *a, int n,int *Len)
{
    int nLISLen = 1;
    B[0] = a[0];
    for(int i = 1; i < n; i++)
    {
        if(a[i] > B[nLISLen - 1])
        {
            B[nLISLen] = a[i];
            nLISLen++;
            Len[i]=nLISLen;
        }
        else
        {
            int pos = BinarySearch(B, a[i], nLISLen);
            B[pos] = a[i];
            Len[i]=pos+1;
        }
    }
    return nLISLen;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    double a[Max]={0};
    double b[Max]={0};
    l[0]=r[0]=1;
    for(int i=0; i<n; i++)
    {
        scanf("%f",a+i);
        b[n-i-1]=a[i];
    }
    LIS_DP_NlogN(a,n,l);
    LIS_DP_NlogN(b,n,r);
    int maxlen=0;
    for(int i=0;i<n-1;i++)
        for(int j=n-i-2;j>=0;j--)
            maxlen=max(maxlen,l[i]+r[j]);
    printf("%d\n",n-maxlen);
    return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved