【决策单调性】P3648 [APIO2014] 序列分割 题解

news/2024/12/14 16:38:41/文章来源:https://www.cnblogs.com/aquizahv/p/18606907

题目链接:P3648 [APIO2014] 序列分割

(注:由于本题解的状态转移方程需要用到 \(k\),所以原题中的 \(k\) 对应本题解中的 \(m\)。)

给你一个长度为 \(n\) 的序列 \(A_1,A_2,...,A_n\),一开始把它看作一个块。初始你的分数为 \(0\),现在你需要进行下列操作恰好 \(m\) 次:

  • 选一个块,并从一处断开,使得断开的两个块不为空。此时这两个块里的数的和的乘积将加到你的分数里。

求最终分数的最大值,并输出断开的位置。

\(2 \le n \le 10^5,1\le m\le\min\{n-1,200\},0\le A_i\le 10^4\)


转化

这个分数的计算有点绕啊!我们考虑一下两个位置 \((i,j)\) 的贡献吧:不难发现,当且仅当这两个位置最终不在一个块内时,对答案产生 \(A_i \times A_j\) 的贡献。

还是很难算,每个位置要统计一下外面所有位置的贡献。那直接反过来不就好了,我们直接累加每个块内的和的平方。那么答案就是:

\[\frac{(\sum_{i=1}^{n} A_i)^2-sum}{2} \]

于是我们就成功把原问题转化为了这么一个问题:

有一个长度为 \(n\) 的序列,现在要将序列划分为 \(m+1\) 段,最小化各段和的平方之和。

DP

考虑 dp,设 \(f_{k,i}\) 表示第 \(k\) 段的末尾是 \(i\),当前的总和的最小值。

则有

\[f_{k,i}=\min_{k\le j\le i}\{f_{k-1,j - 1} + (\sum_{l=j}^i A_l)^2\} \]

此时 \(f_k\) 是有决策单调性(即 \(i<j\) 两个位置的决策点 \(op_i\le op_j\))的,下面讲讲为什么:

四边形不等式与决策单调性

假设我们要解决如下一类问题:

\[f_{i} = \min_{1\le j \le i} w(i,j) \]

若对于 \(a<b<c<d\),有

\[w(a,c)+w(b,d)\le w(a,d)+w(b,c) \]

那么称函数 \(w\) 满足「四边形不等式」。此时 \(f_i\) 具有决策单调性。证明不再赘述,想了解可以前往 OI Wiki - 四边形不等式优化。

回到这题,假设当前外层循环是 \(k\),我们令 \(w(i,j)\) 表示 \(f_{k,i - 1} + \sum_{l=j}^i A_l)^2\)。那么它是否满足四边形不等式呢?

假设有四个位置 \(a\le b\le c\le d\),并且有

\[\begin{cases} X=\sum_{a\le i < b} A_i\\ Y=\sum_{b\le i\le c} A_i\\ Z=\sum_{c < i\le d} A_i \end{cases} \]

\[\begin{aligned} w(a,c)+w(b,d)&=f_{k,a-1}+(X+Y)^2+f_{k,b-1}+(Y+Z)^2\\ &=f_{k,a-1}+f_{k,b-1}+X^2+2Y^2+Z^2+2XY+2YZ\\ \\ w(a,d)+w(b,c)&=f_{k,a-1}+(X+Y+Z)^2+f_{k,b-1}+Y^2\\ &=f_{k,a-1}+f_{k,b-1}+X^2+2Y^2+Z^2+2XY+2YZ+2ZX \end{aligned} \]

所以有

\[w(a,c)+w(b,d) \le w(a,d)+w(b,c) \]

\(w\) 满足四边形不等式,故 \(f_k\) 具有决策单调性。


所以就可以放心分治优化 dp 了。对于每次递归 \((l,r,x,y)\) 表示 \([l,r]\) 的 dp 值待计算,并且决策点位于 \([x,y]\)。每次遍历 \([x,y]\),计算 \(mid=\lfloor\frac{l+r}{2}\rfloor\) 位置的 dp 值,然后递归 \((l,mid-1,x,op_{mid})\)\((mid+1,r,op_{mid},y)\)

时间复杂度 \(O(mn\log n)\)

// Author: Aquizahv
#include <bits/stdc++.h>
#define ll long long
#define sq(x) (x) * (x)
using namespace std;
const int N = 1e5 + 5, M = 205;
int n, m, a[N], k, op[M][N];
ll sum[N], dp[M][N];ll cal(int l, int r)
{return sq(sum[r] - sum[l - 1]);
}void solve(int l, int r, int x, int y)
{int mid = (l + r) >> 1;for (int i = x; i <= y && i <= mid; i++){ll w = dp[k - 1][i - 1] + cal(i, mid);if (dp[k][mid] > w){dp[k][mid] = w;op[k][mid] = i;}}if (l < mid)solve(l, mid - 1, x, op[k][mid]);if (mid < r)solve(mid + 1, r, op[k][mid], y);
}int main()
{cin >> n >> m;m++;for (int i = 1; i <= n; i++)scanf("%d", a + i), sum[i] = sum[i - 1] + a[i];memset(dp, 0x3f, sizeof(dp));dp[0][0] = 0;for (k = 1; k <= m; k++)solve(1, n, 1, n);cout << (sq(sum[n]) - dp[m][n]) / 2 << endl;vector<int> res;int pre = op[m][n] - 1;for (k = m ; k > 1; k--){res.push_back(pre);pre = op[k - 1][pre] - 1;}while (!res.empty()){printf("%d ", res.back());res.pop_back();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/852565.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024-2025-1 20241305《计算机基础与程序设计》第十二周学习总结

------------恢复内容开始------------ 作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计(https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP))这个作业要求在哪里 2024-2025-1计算机基础与程序设计第十二周作业这个作业的目标 指针和数组作业正文 本博客…

微信小程序商城构建全栈应用

D:\PanDownload\【微信小程序】\微信小程序商城构建全栈应用 第1章 前言:不同的时代,不同的Web 1-1 前言与导语 导语 好的课程需要包含俩方面: 一:整体的思路与编程思想(大局观,AOP ,10~20%) 二:具体的编程知识与技巧(TP5,小程序,数据库等80%) books+code 1-2 产品所使用的技…

龍兄虎弟 综艺 All In One

龍兄虎弟 综艺 All In One 主持人:張菲、費玉清龍兄虎弟 综艺 All In One主持人:張菲、費玉清精彩片段 https://www.youtube.com/watch?v=fD1MxE9e3Bg&list=PLtww_vcpAB8pJn3goLppo42EDqjt8t1kh完整版 https://www.youtube.com/watch?v=67MJj22yMp0&list=PLRWrniKO…

UWB物理层实现-特殊汉明码纠错

根据802.15.4协议,chapter15.2.7,PHR部分的编码,除了一些控制参数外,在后面添加了6位单错纠正双错检测码(SECDED),用于纠错能力的提升,这6位汉明码为PHR部分提供了至少1bit的纠错能力,以及至少2bit的检错能力。此码块由汉明码构成,与一般汉明码不同的是,改码并没有穿…

NestJS导出API文档

在NestJS中,你可以使用@nestjs/swagger包来定义你的API文档,并且可以很容易地将这些文档转换为API调用。以下是一个简单的例子,展示如何使用NestJS和Swagger来创建一个API文档,并且如何生成API调用。 首先,安装@nestjs/swagger和swagger-ui-express:npm install @nestjs/…

python版本切换

1、搜索框输入:环境变量2、在下面的系统变量:选择path -> 点击:编辑3、将需要的python版本上移到上面,调整好后,一路点击确定关闭几个打开的窗口,保存环境变量配置。3、打开cmd,输入:python --version 确认版本是否切换成功

机器学习期末复习笔记

机器学习期末复习机器学习期末复习笔记 简介 主要注重决策树的计算,朴素贝叶斯,PCA降维的计算 笔记

07相关软件的安装以及HTML介绍

一、内容回顾这个软件从1.0就开始收费了,这里使用这个版本这里将侧边栏打开 这个typora软件支持Markdown的格式,markdown格式是我们经常会使用到的笔记格式的形式,后缀名是md 这种语法在整理笔记是比较方便的 1、标题 加上#号表示是标题,这个和H1,H2...标签类似 加上不同的…

Threejs教程,2024全新系统threejs入门教程

Threejs教程,2024全新系统threejs入门教程 https://www.bilibili.com/video/BV1Zm421g7oi/?spm_id_from=333.999.0.0 2 4 01-theejs三要素 WebGL 顶点数据 顶点索引 矩阵 三要素 场景 Scene 容器 相机 Camera 观察 渲染器Renderer 组合 透视相机(PerspectiveCamera) htt…

命令行下php加载模块

命令行下php加载模块 在命令行下使用 PHP 加载模块,你可以使用 -d 选项来设置 php.ini 中的设置,或者使用 dl() 函数来动态加载 PHP 扩展模块。 例如,如果你想要加载一个名为 my_module.so 的模块,你可以这样做: php -d "extension=my_module.so" script.php &l…

虚拟机配置rsync同步

虚拟机配置rsync同步安装 apt install rsync修改配置文件 vim /etc/rsyncd.confuid = nobody gid = nogroup use chroot = no max connections = 4 pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log[html]path = /home/xuxb/ht…

PHP实现开源Consul服务发现与治理

PHP实现开源Consul服务发现与治理 在分布式系统中,服务发现和治理是必不可少的组成部分。其中,consul作为一款服务发现和治理工具,被广泛应用于微服务架构中。本文将介绍如何使用php实现开源consul服务发现与治理。 一、什么是Consul? Consul是一款由HashiCorp公司开发的服…