#include<bits/stdc++.h>
using namespace std;

const int N = 1;

/*
1.枚举i,表示从第一个序列得到长度为i字典序最大的子序列,从第二序列得到长度为k-i的字典序最大的子序列
2.写一个求序列a 长度为k1,字典序最大的子序列的函数
单调栈去做:假设a的长度是n,那么也就意味着我们要抛弃n-k1个数

3.写一个能合并通过2得到的两个序列的函数,保证合并的两个序列字典序也是最大的
6 6 3
6 7 3

6 7 3
6 6 3
注意细节:当遇到相同数字时,合并要优先选后缀字典序最大的

4.更新答案,比较和之前的答案谁大,大就更新。。。


*/
//从a中得到长度k的字典序最大的子序列


int cmp(vector<int> a, int ida, vector<int> b, int idb) {
	int len1 = a.size(), len2 = b.size();
	while(ida < len1 && idb < len2) {
		if(a[ida] != b[idb]) return a[ida] > b[idb];
		
		ida ++, idb ++;
	}
	if(ida < len1) return 1;
	else return 0;
}


vector<int> get(vector<int> a, int k) {
	int n = a.size();
	if(n <= k) return a;
	
	int t = n - k; //需要剔除t个数字,留下k个
	vector<int> stk;
	for(int i = 0; i < n; i++) {
		while(stk.size() > 0 && stk.back() < a[i] && t > 0) {
			stk.pop_back();
			t --;
		}
		if(stk.size() < k) stk.push_back(a[i]);
		else t --;
	}
	return stk;
}

vector<int> merge(vector<int> a, vector<int> b) {
	int len1 = a.size(), len2 = b.size();
	
	vector<int> res;
	
	int i = 0, j = 0;
	while(i < len1 && j < len2) {
		if(a[i] > b[j]) res.push_back(a[i ++]);
		else if(a[i] < b[j]) res.push_back(b[j ++]);
		else {
			if(cmp(a, i, b, j) > 0) res.push_back(a[i ++]);
			else res.push_back(b[j ++]);
		}
	}
	
	while(i < len1) res.push_back(a[i ++]);
	while(j < len2) res.push_back(b[j ++]);
	
	return res;
}

int main()
{
	int n, m, k;
	cin >> n >> m >> k;
	vector<int> a, b;
	for(int i = 1; i <= n; i++) 
	{
		int x;
		cin >> x;
		a.push_back(x);
	}
	
	for(int i = 1; i <= m; i++) {
		int x;
		cin >> x;
		b.push_back(x);
	}
	vector<int> ans(k, 0);
	//枚举长度
	for(int i = 0; i <= k; i++) {
		int len1 = i, len2 = k - i;
		vector<int> tmp1 = get(a, len1); //从a中得到长度为len1的字典序最大的子序列
		vector<int> tmp2 = get(b, len2);
		
		vector<int> res = merge(tmp1, tmp2); //合并两个子序列
		if(res.size() == k && cmp(res, 0, ans, 0) > 0) ans = res;
	}
	
	for(auto x : ans) cout << x;
	
	return 0;
}

0 条评论

目前还没有评论...