• hdu 5125(LIS变形)


    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5125

    题解:

    这个题dp[i][0],dp[i][1]数组分别记录在第i个位置取a[i]和b[i]时可以取到最长上升子序列的长度,然后开一个m[i][0]和m[i][1]分别表示取到第i个位置时最少的交换次数.然后进行4次比较,最后取最大值的时候非常巧妙,如果m[i][0]>M,那么证明这个序列里面多了 m[i][0]-M 个数,所以要减掉这么多个数.

    蒟蒻感觉别人好强啊....

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include <queue>
    using namespace std;
    const int N = 1005;
    int a[N],b[N],dp[N][2],m[N][2];
    int main()
    {
        int tcase;
        scanf("%d",&tcase);
        while(tcase--){
            int n,M;
            scanf("%d%d",&n,&M);
            for(int i=1;i<=n;i++){
                scanf("%d%d",&a[i],&b[i]);
            }
            memset(m,0,sizeof(m));
            memset(dp,0,sizeof(dp));
            dp[1][1] = dp[1][0]=m[1][1] =1;
            for(int i=2;i<=n;i++){
                dp[i][1]=dp[i][0] = m[i][1] =1;
                for(int j=1;j<i;j++){
                    if(a[i]>a[j]){
                        if(dp[i][0]<dp[j][0]+1||dp[i][0]==dp[j][0]+1&&m[i][0]>m[j][0]){
                            dp[i][0] = dp[j][0]+1;
                            m[i][0] = m[j][0];
                        }
                    }if(a[i]>b[j]){
                        if(dp[i][0]<dp[j][1]+1||dp[i][0]==dp[j][1]+1&&m[i][0]>m[j][1]){
                            dp[i][0] = dp[j][1]+1;
                            m[i][0] = m[j][1];
                        }
                    }if(b[i]>a[j]){
                        if(dp[i][1]<dp[j][0]+1||dp[i][1]==dp[j][0]+1&&m[i][1]>m[j][0]+1){
                            dp[i][1] = dp[j][0]+1;
                            m[i][1] = m[j][0]+1;
                        }
                    }if(b[i]>b[j]){
                        if(dp[i][1]<dp[j][1]+1||dp[i][1]==dp[j][1]+1&&m[i][1]>m[j][1]+1){
                            dp[i][1] = dp[j][1]+1;
                            m[i][1] = m[j][1]+1;
                        }
                    }
                }
            }
            int MAX = 0;
            for(int i=1;i<=n;i++){
                if(m[i][0]<=M) MAX = max(dp[i][0],MAX);
                else MAX = max(dp[i][0]-m[i][0]+M,MAX);
                if(m[i][1]<=M) MAX = max(dp[i][1],MAX);
                else MAX = max(dp[i][1]-m[i][1]+M,MAX);
            }
            printf("%d
    ",MAX);
        }
        return 0;
    }
  • 相关阅读:
    android的FATAL EXCEPTION: main错误
    ORA12560: TNS: 协议适配器错误
    BroadcastReceiver应用详解
    using C# 详解
    mysqlproxy0.8版本读写分离测试总结
    Mysql SHOW PROCESSLIST Sending data
    [转载]大型网站运维探讨和心得
    找出并optimization表
    mysql中普通索引和唯一索引的效率对比
    ps aux 中STAT 解释
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5666072.html
Copyright © 2020-2023  润新知