CF4D Mysterious Present (dp)

这道题是最长上升子序列求方案数的题目

对于这种题目,需要多几个变量,一个是前置,一个是当前id 因为我们肯定想到要对他进行排序

在求方案数的时候只需要从末端一直往前缀走就行,直到-1

这题因为前提要大于这个信,所以在输入时需要判断一下

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
int ans[5010];
struct node{
    int w,h,pre,len,id;
    int sign;
}s[N];
bool cmp(node a,node b){
    if(a.w==b.w)
        return a.h<b.h;
    return a.w<b.w;
}
int main(){
    int n,a,b;
    cin>>n>>a>>b;
    int i;
    for(i=1;i<=n;i++){
        cin>>s[i].w>>s[i].h;
        s[i].id=i,s[i].pre=-1,s[i].len=1;
        if(s[i].w>a&&s[i].h>b){
            s[i].sign=1;
        }
        else{
            s[i].sign=0;
        }
    }
    int cnt=-1;
    int res=0;
    sort(s+1,s+n+1,cmp);
    for(i=1;i<=n;i++){
        if(!s[i].sign)
            continue;
        int j;
        for(j=1;j<=n;j++){
            if(!s[j].sign)
                continue;
            if(s[i].w>s[j].w&&s[i].h>s[j].h){
                int len=s[j].len+1;
                if(len>s[i].len){
                    s[i].len=len;
                    s[i].pre=j;
                }
            }
        }
        if(s[i].len>res){
            res=s[i].len;
            cnt=i;
        }
    }
    if(cnt==-1){
        cout<<0<<endl;
    }
    else{
        int idx=0;
        cout<<s[cnt].len<<endl;
        while(cnt!=-1){
            ans[++idx]=s[cnt].id;
            cnt=s[cnt].pre;
        }
        for(i=idx;i>=1;i--){
            printf("%d ",ans[i]);
        }
        cout<<endl;
    }
}
View Code