CSP202209-5 高维亚空间超频物质变压缩技术

news/2024/12/1 0:49:11/

CSP202209-5高维亚空间超频物质变压缩技术

题意:

给定 n n n 块黄金,每个黄金有体积 v i v_i vi。将黄金分组进行压缩,每一组内的黄金编号连续,压缩一组黄金的代价为 ( s − L ) 2 (s-L)^2 (sL)2 s s s 为改组黄金的体积和。

每块黄金有质量 m i m_i mi,分组必须满足 组之间编号最大的的黄金质量递增。

询问分段压缩的最小代价。

解析:

子任务1,2

f i f_i fi 为前 i i i 块黄金都压缩完成的最小代价。

f i = min ⁡ 0 < j < i { f j + ( s i − s j − L ) 2 } ( m i > m j ) f_i = \min\limits_{0<j<i}\Big\{ f_j + (s_i-s_j-L)^2\Big\}(m_i>m_j) fi=0<j<imin{fj+(sisjL)2}(mi>mj) s s s v v v 的前缀和

初始条件 f 0 = 0 f_0 = 0 f0=0,答案为 f n f_n fn

此时时间时间复杂度为 O ( n 2 ) O(n^2) O(n2)

可以通过前两个测试点

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define fi first
#define se second
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
const int maxn = 1e6+10;
const int maxm = 1e5+10;
const double eps = 1e-12;
const ll INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int, int> pii;
#define int llll n, L;
ll v[maxn], m[maxn], s[maxn];
ll f[maxn];signed main(){ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);cin >> n >> L;for(int i = 1; i <= n; i++){cin >> s[i];s[i] += s[i-1];}for(int i = 1; i <= n; i++)cin >> m[i];memset(f, INF, sizeof(f));f[0] = 0;for(int i = 1; i <= n; i++){for(int j = 0; j < i; j++){ //上一组的终点if(m[i] <= m[j])continue; f[i] = min(f[i], f[j]+(s[i]-s[j]-L) * (s[i]-s[j]-L));}}cout << f[n] << endl;return 0;}


子任务3

因为 m i = i m_i = i mi=i,所以对于 i i i,可以从任意 j ( j < i ) j(j<i) j(j<i) 进行转移。

状态转移方程: f i = min ⁡ 0 < j < i { f j + ( s i − s j − L ) 2 } f_i = \min\limits_{0<j<i}\Big\{ f_j + (s_i-s_j-L)^2\Big\} fi=0<j<imin{fj+(sisjL)2}因为有 s i × s j s_i\times s_j si×sj 项,可以考虑斜率优化。

整理一下: f j + s j 2 + 2 L s j = 2 s i × s j + f i − s i 2 + 2 L s i f_j+s_j^2+2Ls_j = 2s_i\times s_j+f_i-s_i^2+2Ls_i fj+sj2+2Lsj=2si×sj+fisi2+2Lsi确实是可以斜率优化的。 y = f j + s j 2 + 2 L s j , k = 2 s i , x = s j y = f_j+s_j^2+2Ls_j, k = 2s_i, x = s_j y=fj+sj2+2Lsj,k=2si,x=sj

而且 k , x k,x k,x 都是单调的,所以可以用单调队列维护下凸壳。

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define fi first
#define se second
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
const int maxn = 1e6+10;
const int maxm = 1e5+10;
const double eps = 1e-12;
const ll INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int, int> pii;
#define int ll#define x(a) (s[a])
#define y(a) (f[a]+s[a]*s[a]+2*L*s[a]) 
#define k(a) (2*s[a])ll n, L;
ll v[maxn], m[maxn], s[maxn], p[maxn];
int q[maxn], hh = 1, tt = 0;
ll f[maxn];long double slope(int a, int b){long double x1 = (long double)x(a);long double y1 = (long double)y(a);long double x2 = (long double)x(b);long double y2 = (long double)y(b);if(fabs(x2-x1) < eps)return y2 > y1 ? 1e18 : -1e18;elsereturn (y2-y1)/(x2-x1);
}signed main(){ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);cin >> n >> L;for(int i = 1; i <= n; i++){cin >> s[i];s[i] += s[i-1];}for(int i = 1; i <= n; i++)cin >> m[i];if(n <= 2000){	memset(f, INF, sizeof(f));f[0] = 0;for(int i = 1; i <= n; i++){for(int j = 0; j < i; j++){if(m[i] <= m[j])continue; f[i] = min(f[i], f[j]+(s[i]-s[j]-L) * (s[i]-s[j]-L));}}cout << f[n] << endl;return 0;}else{q[++tt] = 0;f[0] = 0;	for(int i = 1; i <= n; i++){while(hh < tt && slope(q[hh], q[hh+1]) <= k(i))hh++;     int j = q[hh];f[i] = f[j] + (s[i]-s[j]-L) * (s[i]-s[j]-L);while(hh < tt && slope(q[tt-1], q[tt]) >= slope(q[tt], i))tt--;				q[++tt] = i;}	cout << f[n] << endl;return 0;}return 0;	
}


子任务4

i i i 的决策点 j j j 必须满足 m j < m i m_j < m_i mj<mi,增加一维偏序,可以CDQ分治。

根据黄金质量分为左右两部分。当左侧的状态值计算完成,用左侧的状态更新右侧的状态,必然满足质量的限制。

用左侧值更新右侧值时,左侧的 x x x 单调,右侧处理成 k k k 单调的情况,可以继续用单调队列维护下凸壳。

时间复杂度为 O ( n log ⁡ 2 n ) O(n\log^2 n) O(nlog2n)

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define fi first
#define se second
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
const int maxn = 1e6+10;
const int maxm = 1e5+10;
const double eps = 1e-12;
const ll INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<int, int> pii;
#define int ll#define x(a) (s[a])
#define y(a) (f[a]+s[a]*s[a]+2*L*s[a]) 
#define k(a) (2*s[a])ll n, L;
ll m[maxn], s[maxn];
int q[maxn], hh = 1, tt = 0;
ll f[maxn];
struct node{int m, id;ll k, x, y;
}a[maxn], tmp[maxn];
bool cmpm(node a, node b){if(a.m == b.m)return a.id < b.id;elsereturn a.m < b.m;
}
bool cmpx(node a, node b){return a.x < b.x;
}
long double slope(int i, int j){long double x1 = (long double)a[i].x;long double y1 = (long double)a[i].y;long double x2 = (long double)a[j].x;long double y2 = (long double)a[j].y;if(fabs(x2-x1) < eps)return y2 > y1 ? 1e18 : -1e18;elsereturn (y2-y1)/(x2-x1);
}void cdq(int ml, int mr, int pl, int pr){if(pl > pr)return;if(ml == mr){for(int i = pl; i <= pr; i++){int j = a[i].id;a[i].y = f[j] + s[j]*s[j] + 2 * L * s[j];}		return; }int mmid = (ml+mr) >> 1;int pmid = upper_bound(a+pl, a+1+pr, (node){mmid, n+1, 0, 0}, cmpm)-a-1;cdq(ml, mmid, pl, pmid);	int hh = 1, tt = 0;for(int i = pl; i <= pmid; i++){while(hh < tt && slope(q[tt-1], q[tt]) >= slope(q[tt], i))tt--;q[++tt] = i;}if(pr > pmid){sort(a+pmid+1, a+pr+1, cmpx);for(int i = pmid+1; i <= pr; i++){while(hh < tt && slope(q[hh], q[hh+1]) <= a[i].k)hh++;if(hh <= tt){int id = a[i].id;int j = a[q[hh]].id;if(id < j)continue;f[id] = min(f[id], f[j]+(s[id]-s[j]-L)*(s[id]-s[j]-L));}}sort(a+pmid+1, a+pr+1, cmpm);}cdq(mmid+1, mr, pmid+1, pr);	sort(a+pl, a+pr+1, cmpx);
}
signed main(){ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);cin >> n >> L;for(int i = 1; i <= n; i++){cin >> s[i];s[i] += s[i-1];}for(int i = 1; i <= n; i++)cin >> m[i];memset(f, INF, sizeof(f));f[1] = (s[1]-L) * (s[1]-L);for(int i = 1; i <= n; i++){a[i].id = i;a[i].m = m[i];a[i].k = 2 * s[i];a[i].x = s[i];f[i] = (s[i]-L) * (s[i]-L);}sort(a+1, a+1+n, cmpm); //按质量排序 cdq(1, n, 1, n);cout << f[n] << endl;return 0;}

http://www.ppmy.cn/news/46521.html

相关文章

VIP + Nginx + Keepalived

VIP&#xff08;Virtual IP Address&#xff09;&#xff0c;虚拟IP地址&#xff0c;主要是用来进行不同主机之间的切换&#xff0c;主要用在服务器的主从切换技术。主从服务器都配置同一个VIP地址&#xff0c;保障系统不间断切换。 Keepalived是高可用解决方案&#xff0c;借助…

前端 + 后端 实现分片上传(断点续传/极速秒传)

先记录下&#xff0c;后面有时间再去实现 可参考链接&#xff1a;vue上传大文件/视频前后端&#xff08;java&#xff09;代码 前端 后端 实现分片上传&#xff08;断点续传/极速秒传&#xff09; 前端slice分片上传&#xff0c;后端用表记录分片索引和分片大小和分片总数&a…

BUUCTF-PWN-pwn1_sctf_2016

下载 放入 ubuntu里查信息 现在这些保护我都没有遇到 以后慢慢做应该是会遇到的 然后进行发现是32 所以我们记住 如果栈溢出漏洞 我们需要4个字节填满基地址 放入ida32 查看字符串 发现 cat flag 敏感字符串 然后我们就看引用 先记住地址 为 0x8048F0D 然后开始进去 发…

FPGA与ASIC的区别

先来看张图&#xff0c;本图体现出了集成电路产业链&#xff1a;设计业、制造业、封测业。 关于制造、封装测试我们看两张图稍作了解即可&#xff1a; 数字IC ASIC设计流程及EDA工具&#xff1a; &#xff08;1&#xff09;了解数字IC设计&#xff1a;在VLSI时代&#xff…

linux驱动开发 - 04_Linux 设备树学习 - DTS语法

文章目录 Linux 设备树学习 - DTS语法1 什么是设备树&#xff1f;2 DTS、DTB和DTC3 DTS 语法3.1 dtsi 头文件3.2 设备节点3.3 标准属性1、compatible 属性2、model 属性3、status 属性4、#address-cells 和#size-cells 属性5、reg 属性6、ranges 属性7、name 属性8、device_typ…

yolov8 做图片分类和 ResNet 的对比

文章大纲 yolo v8 图片分类简介与原理说明训练代码数据集的组织多尺度训练参考内容ResNet简介与原理说明训练代码与使用说明Usage其他 牛逼 分类模型分类效果不好怎么办?参考文献和学习路径自己实现windows 下基于pytorch 图片分类教程yolo v8 图片分类 简介与原理说明 简单…

【NestJs】使用连接mysql企业级开发规范

本篇将介绍如何建立 NestJs 的数据库连接、并使用数据库联表查询。 简介 Nest 与数据库无关&#xff0c;允许您轻松地与任何 SQL 或 NoSQL 数据库集成。根据您的偏好&#xff0c;您有许多可用的选项。一般来说&#xff0c;将 Nest 连接到数据库只需为数据库加载一个适当的 No…

毕业生招聘信息的发布与管理系统(论文+设计)

前 言 当今&#xff0c;人类社会已经进入信息全球化和全球信息化、网络化的高速发展阶段。丰富的网络信息已经成为人们工作、生活、学习中不可缺少的一部分。人们正在逐步适应和习惯于网上贸易、网上购物、网上支付、网上服务和网上娱乐等活动&#xff0c;人类的许多社会活动…