- 七月暑期集训DAY03
第四题题目解析+代码
- @ 2024-7-10 16:41:34
#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 条评论
目前还没有评论...