【洛谷P2215】上升序列

题目大意:给定一个长度为 N 的序列,有 M 个询问,每个询问要求输出长度为 L 的上升子序列,若不存在,输出 impossible,若存在,输出下标字典序最小的一个。

题解:考虑到若 L 大于整个序列的 LIS 的长度,显然无解。反之,则一定有解。输出下标字典序最小,考虑按照下标贪心即可。

代码如下

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=1e4+10;
const double eps=1e-6;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll sqr(ll x){return x*x;}
inline ll read(){
	ll x=0,f=1;char ch;
	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
	return f*x;
}
/*--------------------------------------------------------*/

int n,m,a[maxn],dp[maxn],ub;

void read_and_parse(){
	n=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=n;i>=1;i--){
		dp[i]=1;
		for(int j=i+1;j<=n;j++)if(a[j]>a[i])
			if(dp[i]<dp[j]+1)
				dp[i]=dp[j]+1;
		ub=max(ub,dp[i]);
	}
}

void solve(){
	m=read();
	while(m--){
		int L=read();
		if(L>ub)puts("Impossible");
		else{
			int last=-1;
			for(int j=1;j<=n;j++)
				if(a[j]>last&&dp[j]>=L){
					printf("%d ",a[j]);
					last=a[j],--L;
					if(!L)break;
				}
			puts("");
		}
	}
}

int main(){
	read_and_parse();
	solve();
	return 0;
}

原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10649921.html