我先放个博客免得自己口胡太不清晰导致听不懂。传送门
注:此篇博客并不是完全正确,有些地方有打印错误,不过如果看懂了应该不会有什么影响。
我们定义结构体 w , x , y , z {w,x,y,z} w,x,y,z,w表示此状态下的max,x表示这是第几个组,y表示x组的第y大,z用于状态转移。(因为要保证b为2,在2与3类转移中x+1后正好对应为2)
上马!(其实没啥好瞅的,反正代码是别处薅的 )
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100002;
struct node {
ll w;
int x, y, z;
node() {}
node(const ll W, const int X, const int Y, const int Z) {
w = W;
x = X;
y = Y;
z = Z;
}
bool operator < (node const &t) const {
return w < t.w;
}
};
int k, n, cnt, id[N];
vector <int> v[N];
priority_queue <node> q;
bool cmp(const int x, const int y) {
return x > y;
}
bool cmp1(const int x, const int y) {
return v[x][0] - v[x][1] < v[y][0] - v[y][1];
}
int main() {
int len;
ll a, sum = 0;
scanf("%d %d", &k, &n);
for(int i = 1; i <= k; i ++) {
scanf("%d", &len);
if(len == 1) {
scanf("%lld", &a);
sum += a;
}
else {
cnt ++;
for(int j = 1; j <= len; j ++) {
scanf("%lld", &a);
v[cnt].push_back(a);
}
sort(v[cnt].begin(), v[cnt].end(), cmp);
}
}
k = cnt;
for(int i = 1; i <= k; i ++)
id[i] = i, sum += v[i][0];
sort(id + 1, id + k + 1, cmp1);
q.push(node(sum, 1, 1, 0));
while(n --) {
node t = q.top();
q.pop();
printf("%lld ", t.w);
if(t.y < v[id[t.x]].size())
q.push(node(t.w - v[id[t.x]][t.y - 1] + v[id[t.x]][t.y], t.x, t.y + 1, 0));
if(t.x < k)
q.push(node(t.w - v[id[t.x + 1]][0] + v[id[t.x + 1]][1], t.x + 1, 2, 1));
if(t.x < k && t.z == 1)
q.push(node(t.w - v[id[t.x + 1]][0] + v[id[t.x + 1]][1] - v[id[t.x]][1] + v[id[t.x]][0], t.x + 1, 2, 1));
}
return 0;
}
拜拜!