| input | output | 
|---|---|
| 8 8 7 1 6 4 3 5 2 | 3 5 1 4 5 8 7 6 3 2 | 
| 6 3 5 1 2 6 4 | 3 3 3 5 6 1 2 4 | 
| 6 3 5 2 1 6 4 | Fail | 
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
#define ls 2*i
#define rs 2*i+1
#define up(i,x,y) for(i=x;i<=y;i++)
#define down(i,x,y) for(i=x;i>=y;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define w(a) while(a)
#define LL long long
const double pi = acos(-1.0);
#define Len 100005
#define mod 1000000007
const int INF = 0x3f3f3f3f;
//0为递增,1为递减
struct node
{
    int x,y;
} s[Len][2];//记录路径
int n;
int a[Len];
int dp[Len][2];//dp[i][j],保存的就是看在j状态下,第i个位置所在的连续递增或递减序列,最前面那个比这个连续序列第一个大或者小的数
vector<int> ans[2];
void upp(int x,int y,int i,int j,int m)
{
    if(dp[x][y]>m)
    {
        dp[x][y] = m;
        s[x][y].x = i;
        s[x][y].y = j;
    }
}
void downn(int x,int y,int i,int j,int m)
{
    if(dp[x][y]<m)
    {
        dp[x][y] = m;
        s[x][y].x = i;
        s[x][y].y = j;
    }
}
//全递增
int set1()
{
    int i,j;
    dp[1][0] = dp[1][1] = -1;
    up(i,1,n-1)
    {
        dp[i+1][0]=dp[i+1][1] = INF;
        up(j,0,1)
        {
            if(dp[i][j]<INF)
            {
                if(a[i-1]<a[i])//数组的下标对应dp的下标+1,也就是说i对应i+1
                    upp(i+1,j,i,j,dp[i][j]);
                if(dp[i][j]<a[i])//如果不满足j条件下的递增,那么就看能否保存到j^1的条件下
                    upp(i+1,j^1,i,j,a[i-1]);
            }
        }
    }
    return dp[n][0]+dp[n][1]<INF;
}
//全递减
int set2()
{
    int i,j;
    dp[1][0] = dp[1][1] = INF;
    up(i,1,n-1)
    {
        dp[i+1][0]=dp[i+1][1] = -1;
        up(j,0,1)
        {
            if(dp[i][j]>=0)
            {
                if(a[i-1]>a[i])
                    downn(i+1,j,i,j,dp[i][j]);
                if(dp[i][j]>a[i])
                    downn(i+1,j^1,i,j,a[i-1]);
            }
        }
    }
    return dp[n][0]+dp[n][1]>0;
}
//一个递增,一个递减
int set3()
{
    int i,j;
    dp[1][0] = INF;
    dp[1][1] = -1;
    up(i,1,n-1)
    {
        dp[i+1][0] = -1;
        dp[i+1][1] = INF;
        if(dp[i][0]>0)
        {
            if(a[i-1]<a[i])
                downn(i+1,0,i,0,dp[i][0]);
            if(dp[i][0]>a[i])
                upp(i+1,1,i,0,a[i-1]);
        }
        if(dp[i][1]<INF)
        {
            if(a[i-1]>a[i])
                upp(i+1,1,i,1,dp[i][1]);
            if(dp[i][1]<a[i])
                downn(i+1,0,i,1,a[i-1]);
        }
    }
    return dp[n][0]>0 || dp[n][1]<INF;
}
void solve(int x,int y)
{
    if(x<=0) return;
    ans[y].push_back(a[x-1]);
    solve(s[x][y].x,s[x][y].y);
}
int main()
{
    int i,j,k;
    w(~scanf("%d",&n))
    {
        mem(s,0);
        up(i,0,n-1)
        scanf("%d",&a[i]);
        if(set1() || set2() || set3())//三个只要有一个符合即可
        {
            ans[0].clear();
            ans[1].clear();
            if(dp[n][0]>=1 && dp[n][0]<=n) solve(n,0);
            else solve(n,1);
            up(i,0,1)
            {
                if(ans[i].empty())//如果整个序列是递增或者递减,那么取出一个来
                {
                    ans[i].push_back(ans[i^1].back());
                    ans[i^1].pop_back();
                }
            }
            printf("%d %d\n",ans[0].size(),ans[1].size());
            up(i,0,1)
            {
                down(j,ans[i].size()-1,0)
                {
                    printf("%d",ans[i][j]);
                    if(j)
                        printf(" ");
                }
                printf("\n");
            }
        }
        else
            puts("Fail");
    }
    return 0;
}
原文地址:http://blog.csdn.net/libin56842/article/details/45141875