Codeforces Beta Round #4 (Div. 2 Only) 最长上升子序列

题意:给出若干个矩形的上下边,如定义的边界,求大于这个边界 且 长和宽递增的最长矩阵序列 并 输出

分析:对宽排序 , 对长进行DP 最长上升子序列 处理

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define re(i,n) for(int i=0;i<n;i++)
const int maxn = 100100;
int dp[maxn];
int pre[maxn];
struct Pan {
    int a, b , id;
}pan[maxn];
bool cmp(Pan x , Pan y) {
    return x.b < y.b || ( x.b == y.b && x.a < y.a );
}
int cnt , n , aa , bb;
int ans;
void read_date() {
    cin>>cnt>>aa>>bb;
    n = 0;
    for(int i=1;i<=cnt;i++) {
        cin>>pan[n].a>>pan[n].b;
        pan[n].id = i;
        if(pan[n].a>aa && pan[n].b>bb) n++;
    }
    sort(pan,pan+n,cmp);
}
void dfs(int num) {
    if(pre[num]==-1) { cout<<pan[num].id;   return; }
    dfs(pre[num]);
    cout<<" "<<pan[num].id;
}
void solve() {
    ans = 0;
    memset(pre,-1,sizeof(pre));
    re(i,n) {
        re(j,i)
            if(pan[j].a < pan[i].a && pan[j].b < pan[i].b)
                if(dp[j]+1 > dp[i]) { dp[i] = dp[j] + 1; pre[i] = j; }
        if(pre[i] == -1) dp[i] = 1;
    }
    re(i,n) if(dp[i] > ans) ans = dp[i];
    cout<<ans<<endl;
    for(int i=n-1;i>=0;i--) {
        if(dp[i] == ans) {
            dfs(i);
            break;
        }
    }
    cout<<endl;
}
int main() {
    read_date();
    solve();
    return 0;
}
posted @ 2012-07-02 23:43  lenohoo  阅读(227)  评论(0编辑  收藏  举报