[Open Ural FU Personal Contest 2013]E.Pear Trees wuyiqi's method

1965. Pear Trees

Time limit: 1.0 second
Memory limit: 64 MB

题目链接

http://acm.timus.ru/problem.aspx?space=1&num=1965

题目叙述

给 一个 n 个数的排列
n < 1e5
问是否可以将这个排列拆成两个子序列
使得子序列严格递增 | 递减
比如
6
3 5 1 2 6 4
拆成
3 5 6
1 2 4
这样


8 7 1 6 4 3 5 2 拆成 —— 
1 4 5
8 7 6 3 2
这样


Code

const int N = 1e5 + 9;
/**
0 for increase
1 for decrease
*/
int n;
int dp[N][4] , belong[N][4] , A[N] , pre[N][4];
/**
dp          the minimum | maximum number when chose i to be the first sequence
belong      which sequence will the number belong   0 | 1
pre         how to transform
*/
bool update(int x , int y , int mask){
    if (x == -1) return true;
    return ((x > y) ^ mask);
}

void solve(){
    for (int i = 0 ; i < n ; ++i) scanf("%d" , &A[i]);
    FLC(dp , -1);
    RST(belong);
    dp[0][0] = dp[0][1] = 0;
    dp[0][2] = dp[0][3] = INF;
    for (int i = 0 ; i < n - 1; ++i)
    for (int j = 0 ; j < 4 ; ++j) if (~dp[i][j]){
        int first = j & 1;
        int second = j >> 1;
        if ((A[i + 1] > A[i]) ^ first){     // can update first sequence
            if (update(dp[i + 1][j] , dp[i][j] , second)){
                dp[i + 1][j] = dp[i][j];
                belong[i + 1][j] = belong[i][j];
                pre[i + 1][j] = j;
            }
        }
        if ((A[i + 1] > dp[i][j]) ^ second){ // swap two sequence
            int jj = first << 1 | second;
            if (update(dp[i + 1][jj] , A[i] , first)){
                dp[i + 1][jj] = A[i];
                belong[i + 1][jj] = belong[i][j] ^ 1;
                pre[i + 1][jj] = j;
            }
        }
    }
    VI ans[2]{};
    for (int j = 0 ; j < 4 ; ++j) if (~dp[n - 1][j]){
//            puts("Gosh");
        for (int i = n - 1 ; i >= 0 ; --i){
            ans[ belong[i][j] ].PB(A[i]);
            j = pre[i][j];
        }
        reverse(ALL(ans[0]));
        reverse(ALL(ans[1]));
        if (!SZ(ans[1])){
            ans[1].PB(ans[0].back());
            ans[0].pop_back();
        }
        printf("%d %d\n" , SZ(ans[0]) , SZ(ans[1]));
        for (int i = 0 ; i < SZ(ans[0]) ; ++i){
            if (i) printf(" ");
            printf("%d" , ans[0][i]);
        }
        puts("");
        for (int i = 0 ; i < SZ(ans[1]) ; ++i){
            if (i) printf(" ");
            printf("%d" , ans[1][i]);
        }
        puts("");
        return;
    }
    puts("Fail");

}
int main(){
    while(cin >> n) solve();
}


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下 4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值