网址如下:146. 序列 - AcWing题库
有点坑,这题
刚开始我写的代码选择的序列是有遗漏的,直接WA,然后我继续对全局进行处理,但是一次求最小插入的节点太多了,直接MLE,最后是看算法书里的解,发现是先对两个序列求前n小的序列,得到的新序列有可以和下一个序列求前n小,以此类推,最后就求到题目要求的序列
MLE代码:
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 2010;
const int maxm = 1010;
int m, n;
int A[maxm][maxn];
struct Node{
int p[maxm];
int last;
Node():p{}, last(m){}
bool operator<(const Node &tt)const{
int sum = 0, tt_sum = 0;
for(int i = 0; i < m; i++){sum += A[i][p[i]]; tt_sum += A[i][tt.p[i]];}
return sum > tt_sum;
}
};
int main(void)
{
int T; scanf("%d", &T);
while(T--){
scanf("%d%d", &m, &n);
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++)
scanf("%d", &A[i][j]);
sort(A[i], A[i] + n);
}
//开始计算
priority_queue<Node, vector<Node> > pq; pq.push(Node());
for(int i = 0; i < n; i++){
Node u = pq.top(); pq.pop();
int last = u.last, ans = 0;
for(int i = 0; i < m; i++) ans += A[i][u.p[i]]; printf("%d ", ans);
for(int i = 0; i < last; i++){
u.p[i]++; u.last = i + 1;
if(u.p[i] < n) pq.push(u);
u.p[i]--;
}
}
putchar('\n');
}
return 0;
}
AC代码:
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 2010;
const int maxm = 1010;
int m, n;
int A[maxn], B[maxn], res[maxn];
struct Node{
int i, j;
bool last;
Node():i(0), j(0), last(false){}
Node(int i, int j, bool last):i(i), j(j), last(last){}
bool operator<(const Node &tt)const{return A[i] + B[j] > A[tt.i] + B[tt.j];}
};
inline void join(void){
priority_queue<Node, vector<Node> > pq; pq.push(Node());
for(int i = 0; i < n; i++){
Node u = pq.top(); pq.pop();
if(!u.last && u.i + 1 < n) pq.push(Node(u.i + 1, u.j, false));
if(u.j + 1 < n) pq.push(Node(u.i, u.j + 1, true));
res[i] = A[u.i] + B[u.j];
}
memcpy(A, res, sizeof(A));
}
int main(void)
{
int T; scanf("%d", &T);
while(T--){
scanf("%d%d", &m, &n);
for(int i = 0; i < n; i++) scanf("%d", &A[i]);
sort(A, A + n);
for(int i = 1; i < m; i++){
for(int j = 0; j < n; j++) scanf("%d", &B[j]);
sort(B, B + n);
join();
}
for(int i = 0; i < n; i++) printf("%d ", A[i]);
putchar('\n');
}
return 0;
}