https://www.luogu.org/problem/P2215

初看题目,不就是个最长上升子序列吗?

但我们知道nlogn的最长上升子序列中定义状态f[i]表示以i结尾的...

这个题要求以i开头

所以倒着做最长下降子序列就好了,f只记录长度(解题关键,逆向思考)

但我发现我一直wa

wa的代码:

#include<bits/stdc++.h>
#define ll long long
#define il inline
#define ri register int
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=10005;
int n,m,maxx;
int dp[maxn],C[maxn],a[maxn],t[maxn],xx[maxn];
il void add(int x,int p){while(x)C[x]=max(C[x],p),x-=lowbit(x);return;}
il int query(int x){int res=0;while(x<=n)res=max(res,C[x]),x+=lowbit(x);return res;}
int main(){
    scanf("%d",&n);
    for(ri i=1;i<=n;i++)scanf("%d",&a[i]),t[i]=xx[i]=a[i];
    sort(t+1,t+1+n);int sz=unique(t+1,t+1+n)-t-1;
    for(ri i=1;i<=n;i++)a[i]=lower_bound(t+1,t+1+n,a[i])-t;
    for(ri i=n;i>=1;i--){
    dp[i]=query(a[i]+1)+1;
    add(a[i],dp[i]);
    maxx=max(maxx,dp[i]);
    }
    scanf("%d",&m);
    while(m--){int x;scanf("%d",&x);
    if(x>maxx){printf("Impossible\n");continue;}
    for(ri i=1;i<=n;i++){
        if(!x){cout<<endl;break;}
        if(dp[i]==x)printf("%d ",xx[i]),x--;
    }
    }
    return 0;
}

为什么呢?因为我太弱了。

输出的时候根本无法满足它是最长上升的,我只转移了长度

AC CODE

#include<bits/stdc++.h>
#define ll long long
#define il inline
#define ri register int
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=10005;
int n,m,maxx;
int dp[maxn],C[maxn],a[maxn],t[maxn],xx[maxn];
il void add(int x,int p){while(x)C[x]=max(C[x],p),x-=lowbit(x);return;}
il int query(int x){int res=0;while(x<=n)res=max(res,C[x]),x+=lowbit(x);return res;}
int main(){
    scanf("%d",&n);
    for(ri i=1;i<=n;i++)scanf("%d",&a[i]),t[i]=xx[i]=a[i];
    sort(t+1,t+1+n);int sz=unique(t+1,t+1+n)-t-1;
    for(ri i=1;i<=n;i++)a[i]=lower_bound(t+1,t+1+n,a[i])-t;
    for(ri i=n;i>=1;i--){
    dp[i]=query(a[i]+1)+1;
    add(a[i],dp[i]);
    maxx=max(maxx,dp[i]);
    }
    scanf("%d",&m);
    while(m--){int x;scanf("%d",&x);
    if(x>maxx){printf("Impossible\n");continue;}
    int last=0;
    for(ri i=1;i<=n;i++)
        if(dp[i]>=x&&xx[i]>last){
        printf("%d ",xx[i]),x--,last=xx[i];
        if(!x)break;
        } puts("");
    }
    return 0;
}
02-11 02:14