首页 > 其他分享 >LOJ #6039「雅礼集训 2017 Day5」珠宝

LOJ #6039「雅礼集训 2017 Day5」珠宝

时间:2023-08-10 21:33:41浏览次数:39  
标签:val leq LOJ Day5 pos 雅礼 int 物品 mx

给定 \(n\) 个物品,第 \(i\) 个物品有体积 \(c_i\),价值 \(v_i\)。给定 \(K\),对 \(1 \sim K\) 的所有 \(i\) 求大小为 \(i\) 的背包的最大价值。
\(n \leq 10^6\),\(K \leq 5 \times 10^4\),\(c_i \leq 300\),\(0 \leq v_i \leq 10^9\),时限 \(\text{2.0s}\)。


注意到 \(c_i\) 范围很小,考虑往 \(\mathcal{O}(CK)\) 之类的东西上靠一靠。我们把 \(c_i\) 相同的物品放在一起并按 \(v_i\) 排序,那么取的一定是一段前缀。更进一步地,设 \(g_i\) 为 \(c_k = i\) 的物品对应的结果,即 \(g_{i,j}\) 为取 \(j\) 个体积为 \(i\) 的物品的最大价值,那么 \(g_i\) 是凸的。

所以我们就搞出了 \(\mathcal{O}(C)\) 个凸包,很乱斗。考虑每次怎么把一个凸包合并到答案上,假设枚举了当前的体积 \(c\),那么答案数组中下标 \(\bmod c\) 不同的位置互不干扰,可以独立做。对每个同余类拉出来之后 DP 大概长成 \(f_i \gets f_j + g_{c,i-j}\) 这个样子,由于 \(g_c\) 上凸并且单调不降,因此它满足四边形不等式,于是有决策单调性,分治即可做到 \(\mathcal{O}(CK\log K)\)。

code
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef vector <LL> vi;
constexpr int M = 3e2 + 5, K = 5e4 + 5, N = 1e6 + 5; 
int n, k, C;
vi f[M], ans, p, q, tmp; int L[M]; 
void trans(int l, int r, int ql, int qr) {
	if (l > r) return;
	int m = l + r >> 1;
	LL mx = 0, pos = 0;
	int rb = min(qr, m);
	for (int i = ql; i <= rb; i++) {
		LL val = 0;
		if (m - i >= q.size()) val = q.back();
		else val = q[m - i];
		if (p[i] + val > mx) mx = p[i] + val, pos = i; 
	}
	tmp[m] = mx;
	trans(l, m - 1, ql, pos);
	trans(m + 1, r, pos, qr);
}
int main() {
	ios :: sync_with_stdio(false);
	cin.tie(nullptr);
	freopen("jewelry.in", "r", stdin);
	freopen("jewelry.out", "w", stdout);
	cin >> n >> k;
	for (int i = 1, c, v; i <= n; i++) {
		cin >> c >> v;
		f[c].push_back(v);
		L[c]++;
		C = max(C, c);
	}	
	for (int i = 1; i <= C; i++) {
		f[i].push_back(0);
		sort(f[i].begin(), f[i].end()), reverse(f[i].begin(), f[i].end());
		for (int j = 1; j < f[i].size(); j++) {
			f[i][j] = f[i][j] + f[i][j - 1];
		} 
		for (int j = f[i].size() - 1; j >= 1; j--) f[i][j] = f[i][j - 1];
		f[i][0] = 0; 
		while (L[i] > K) f[i].pop_back(), L[i]--;
	} 
	ans.resize(k + 1);
	tmp.resize(k + 1);
	for (int c = 1; c <= C; c++) {
		q.clear();
		for (int i = 0; i <= L[c]; i++) q.push_back(f[c][i]);
		for (int i = 1; i <= c; i++) {
			p.clear();
			int j = i;
			if (i == c) p.push_back(0); 
			while (j <= k) p.push_back(ans[j]), j += c;
			trans(0, p.size() - 1, 0, p.size() - 1);
			j = i;
			int o = 0;
			if (i == c) o = 1;
			while (j <= k) ans[j] = tmp[o], j += c, o++;
		}
		for (int i = 1; i <= k; i++) ans[i] = max(ans[i], ans[i - 1]);	
	} 
	for (int i = 1; i <= k; i++) cout << ans[i] << " \n"[i == k];
	return 0;
} 
/*
5 10
3 2
1 48
3 25
2 76
4 83
*/

标签:val,leq,LOJ,Day5,pos,雅礼,int,物品,mx
From: https://www.cnblogs.com/came11ia/p/17621562.html

相关文章

  • vue--day58---多个元素过度
    1.App.vue<template> <div><Test></Test><Test2></Test2></div>  </template> <script> importTestfrom'./components/Test.vue';importTest2from'./components/Test2.vue';......
  • vue--day55--vue 的$nextTick以及MyItem编辑框
    1.语法this.$nextTick(回调函数)2.作用在下一次DOM更新结束后执行其指定的回调3.什么时间用当改变数据后,要基于更新后新的DOM进行某些操作时,要在nextTick所指定的回调函数中执行。1.App.vue<template><divid="root"><divclass="todo-container"><divclass="to......
  • 二维数组花式遍历(旋转,螺旋) [labuladong-刷题打卡 day5]
    矩阵旋转48.旋转图像难点主要在于:用翻转和镜像处理逆反和旋转,和逆转单词一样“难者不会,会者不难”,思路简单镜像的坐标对应关系处理语言特性的利用,不同语言有不同api,实际代码中会有很大不同,但思想一致如果确定矩阵维数,通过线性代数应该可以直接计算答案...classSolution......
  • vue--day54--todolist 中的MyItem 和App 消息发布实现通信
    1.App.vue<template><divid="root"><divclass="todo-container"><divclass="todo-wrap"><!--@addTodo事件名addTodo回调名--><MyHeader@addTodo="addTodo"/><!--父亲给儿子传数据父亲通过数据绑定......
  • vue--day51----todolist 中App.vue 和 MyItem.vue 类似 父亲和子通信 通过全局事件总
    1.mainjs/***该文件是整个项目的入口文件*///引入VueimportVuefrom'vue'//引入App组件他是所有组件的父组件importAppfrom'./App.vue'//关闭vue的生产提示Vue.config.productionTip=false//constDemo=Vue.extend({})//constd=newDemo();//Vue.pr......
  • Week6 Day5
    偶吼吼 今天终于来到了 图形用户接口 终于能接触到有关设计之类的东西了  GUI从创建window开始通常会使用JFrameJFrameframe=newJFrame();可以这样加入按钮、文字字段等: frame.getContentPane().add(button);你得指定尺寸和执行显示动作:frame.setSize(300,300......
  • Python基础day57 Django模板继承和模型层
    模板之标签就是在模板里面使用流程控制:if、else、elseif、for标签看起来是这样的:{%tag%}for标签{%forpersoninperson_list%}{{forloop}}<p>{{person.name}}</p>{%endfor%}{%forpersoninperson_list%}{#判断list是否有值,没有就走empty#}......
  • vue--day50--todolist案例自定义事件修改footer 和header 修改
    1.MyHeader.vue<template><divclass="todo-header"><!--v-model:="title"是实时绑定的--><inputtype="text"placeholder="请输入你的任务名称,回车键确认"v-model="title"@keyup.enter="add"/>......
  • Python基础day56 Django视图层相关
    视图层三板斧问题在视图函数中写函数跟普通函数不太一样,Django中使用的是局部的request所有的视图函数不能够没有返回值,并且返回值还必须是HttpResponse对象#错误代码Theviewapp01.views.indexdidn'treturnanHttpResponseobject.ItreturnedNoneinstead.其实我......
  • LOJ3677 「北大集训 2021」出题高手
    卡死人了。数据随机写在上面,就是让你预估一下区间长度不会太长的,数据里最长的不超过\(2000\)。暴力扫\(2000\)个显然过不了\(500000\)的点,但是\(500000\)的点\(m\)为\(1\)且必定询问整个序列。可以分析出,在随机情况下,前缀和最小最大数量是根号个的,平方后是四次根号级......