朴素算法O(n ^ n)啊,这都能做,想了想,最后只要输出其中和的前k小的就行了,有很多计算是冗余的啊,想了想,每行排个序,然后只算前两列,还有2 ^ k个,取k个绰绰有余了,O(2 ^ n),还能骗点分……扇自己一巴掌,卧槽你以为做PAT呢,还能骗分,然而还是忍不住交了一发……
WA代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
#include <set>
#include <queue>
#include <string>
#include <vector>
using namespace std;
struct node {
int psum;
node() {}
node(int psum) : psum(psum) {}
bool operator < (const node &on) const {
return this->psum > on.psum;
}
};
int k, cnt;
int a[755][755];
priority_queue<node> Q;
void dfs(int dep, int sum) {
if (cnt == 1000000) {
return;
}
if (dep == k) {
Q.push(node(sum));
cnt++;
return;
}
dfs(dep + 1, sum + a[dep][0]);
dfs(dep + 1, sum + a[dep][1]);
}
int main()
{
while (~scanf("%d", &k)) {
for (int i = 0; i < k; i++) {
for (int j = 0; j < k; j++) {
scanf("%d", &a[i][j]);
}
sort(a[i], a[i] + k);
}
while (!Q.empty()) Q.pop();
cnt = 0;
dfs(0, 0);
int c = 0;
while (!Q.empty()) {
printf(c++ == 0 ? "%d" : " %d", Q.top());
Q.pop();
if (c == k) break;
}
puts("");
}
return 0;
}
没仔细想还有没有别的什么错误,不过这O(2 ^ k)的复杂度肯定是不行的……
其实我只想到了一个起点,没想到归并,一列一列往下合并,横向地去求而不是纵向的,不断地往最小堆里扔,每次取最小的再合并再扔,最后时间复杂度O(n²logn)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
#include <set>
#include <queue>
#include <string>
#include <vector>
using namespace std;
struct node {
int a, b;
node() {}
node(int a, int b) : a(a), b(b) {}
bool operator < (const node& on) const {
return this->a > on.a;
}
};
int A[755][755], C[755];
int n;
priority_queue<node> Q;
void Merge(int *A, int *B, int *C) {
while (!Q.empty()) Q.pop();
for (int i = 0; i < n; i++) {
Q.push(node(A[i] + B[0], 0));
}
for (int i = 0; i < n; i++) {
node tn = Q.top(); Q.pop();
int a = tn.a, b = tn.b;
C[i] = a;
if (b + 1 < n) Q.push(node(a - B[b] + B[b + 1], b + 1));
}
}
int main()
{
while (~scanf("%d", &n)) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &A[i][j]);
}
sort(A[i], A[i] + n);
}
memcpy(C, A[0], sizeof(A[0]));
for (int i = 1; i < n; i++) {
Merge(C, A[i], C);
}
printf("%d", C[0]);
for (int i = 1; i < n; i++) {
printf(" %d", C[i]);
}
puts("");
}
return 0;
}