求助,感觉此题用N^2LIS+离线可以做
查看原帖
求助,感觉此题用N^2LIS+离线可以做
65941
welen楼主2020/11/13 08:34

大概做法是这样的,N方的LIS求法。然后把输入的提问离线,从小到大排序。在dp的过程中,顺便解决答案。但是只有10分。。。具体代码如下:

#include<cstdio>
#include<algorithm>

const int MAXN = 1e4+5;
const int MAXM = 1e3+5;
const int INF = 0x3f3f3f3f;
using namespace std;
void readint(int &res){
	res = 0;int f = 1;char ch = getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-'){
			f*=-1;
		}
		ch = getchar();
	}
	while(ch>='0'&&ch<='9'){
		res = res*10+ch-'0';
		ch = getchar();
	}
	res *= f;
	return;
}
int N,M;
struct que{
	int idx,k;
	bool operator<(const que & q)const{
		return k<q.k;
	}
}ques[MAXM];
int ans[MAXM];
int dp[MAXN],pre[MAXN];//pre数组有点类似链表,存i是从哪个位置转移过来的。 
int ora[MAXN];
int st[MAXN];
void print(int p){//输出第i个提问的答案 
	int top = 1,tail = 0;
	for(int i = ans[p];i!=0;i=pre[i]){//因为链表是从后往前存的,所以写了个栈结构,把它从前往后输出。 
		st[++tail]=ora[i];
	}
	if(top>tail){
		printf("Impossible\n");
		return;
	}
	while(tail>=top){
		printf("%d ",st[tail]);
		tail--;
	}
	printf("\n");
	return;
}
int main(){
	readint(N);
	for(int i = 1;i<=N;++i){
		readint(ora[i]);
	}
	readint(M);
	for(int i = 1;i<=M;++i){
		readint(ques[i].k);
		ques[i].idx = i;
	}
	sort(ques+1,ques+M+1);//把提问离线,排序。 
	int p = 1;//标记处理到第几个提问了,有点类似指针 
	for(int i = 1;i<=N;++i){
		int mx = -INF;
		for(int j = 0;j<i;++j){
			if(dp[j]>mx&&ora[j]<ora[i]){
				mx = dp[j];
				dp[i]=dp[j]+1;
				pre[i]=j;//pre数组有点类似链表,存i是从哪个位置转移过来的。 
			}
		}//dp过程 
		while(p<=M){//处理答案 
			if(ques[p].k==dp[i]){
				ans[ques[p].idx]=i;
				++p;
			}else{
				break;
			}
		}
	}
	for(int i = 1;i<=M;++i){
		print(i);
	}
	return 0;
}
2020/11/13 08:34
加载中...