最优卡组

我先放个博客免得自己口胡太不清晰导致听不懂。传送门
注:此篇博客并不是完全正确,有些地方有打印错误,不过如果看懂了应该不会有什么影响。

我们定义结构体 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;
} 

拜拜!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值