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;
}
原文地址:https://www.cnblogs.com/liyinggang/p/5666072.html