信息学奥赛一本通 1610:玩具装箱 | 洛谷 P3195 [HNOI2008] 玩具装箱

【题目链接】

ybt 1610:玩具装箱
洛谷 P3195 [HNOI2008] 玩具装箱

【题目考点】

1. 动态规划:斜率优化动规

斜率优化动规模板题:信息学奥赛一本通 1607:【 例 2】任务安排 2 | 洛谷 P10979 任务安排 2

【解题思路】

玩具长度 C C C序列是由n个整数构成的整数序列。每个容器中放入的玩具是 C C C序列的一个子段。
该问题抽象后为:给定整数序列 C C C,将该序列分为若干个子段,子段[l, r]的费用为 ( r − l + ∑ i = l r C i − L ) 2 (r-l+\sum_{i=l}^rC_i-L)^2 (rl+i=lrCiL)2。对于所有的子段划分方案,求所有子段费用加和最小的方案的费用加和。

1. 状态定义
  • 阶段:前i个元素
  • 决策:确定一个子段
  • 策略:子段划分方案
  • 策略集合:前i个元素的所有子段划分方案
  • 条件:费用加和最小
  • 统计量:费用加和

状态定义 d p i dp_i dpi:前i个元素的所有子段划分方案中,费用加和最小的方案的费用加和。
初始状态 d p 0 dp_0 dp0:前0个元素的费用加和为0。

2. 状态转移方程
  • 策略集合:前i个元素的所有子段划分方案
  • 分割策略集合:最后一个子段的起始位置划分策略集合

设序列 C C C的前缀和数组为 s u m C sumC sumC,则子段 [ l , r ] [l, r] [l,r]的费用为 ( r − l + ∑ i = l r C i − L ) 2 = ( r − l + s u m C r − s u m C l − 1 − L ) 2 (r-l+\sum_{i=l}^rC_i-L)^2 = (r-l+sumC_r-sumC_{l-1}-L)^2 (rl+i=lrCiL)2=(rl+sumCrsumCl1L)2
前i个元素进行子段划分,设最后一个子段为 [ j + 1 , i ] [j+1, i] [j+1,i]
显然j最小为0,整个序列就是最后一个子段。j最大为i-1,此时最后一个子段只有第i元素。j的范围为 0 ≤ j < i 0\le j < i 0j<i
前i个元素的费用加和,为前j个元素进行子段划分的最小费用加和 d p j dp_j dpj加上最后一个子段的费用 ( i − j − 1 + s u m C i − s u m C j − L ) 2 (i-j-1+sumC_i-sumC_j-L)^2 (ij1+sumCisumCjL)2。取所有费用加和的最小值
因此状态转移方程为: d p i = m i n { d p j + ( i − j − 1 + s u m C i − s u m C j − L ) 2 } , 0 ≤ j < i dp_i = min\{dp_j+(i-j-1+sumC_i-sumC_j-L)^2\}, 0\le j < i dpi=min{dpj+(ij1+sumCisumCjL)2},0j<i
S i = s u m C i + i = ∑ j = 1 i C j + i = ∑ j = 1 i ( C j + 1 ) S_i = sumC_i+i = \sum_{j=1}^iC_j+i=\sum_{j=1}^i(C_j+1) Si=sumCi+i=j=1iCj+i=j=1i(Cj+1),因此 S i S_i Si就是 C i + 1 C_i+1 Ci+1的前缀和。
使 L ′ = L + 1 L'=L+1 L=L+1,去掉状态转移方程中的min,方程写为:
d p i = d p j + ( S i − S j − L ′ ) 2 dp_i = dp_j+(S_i-S_j-L')^2 dpi=dpj+(SiSjL)2
将与j相关的量视为变量,整理为
d p i = d p j + ( S i − L ′ ) 2 + S j 2 − 2 ( S i − L ′ ) S j dp_i = dp_j+(S_i-L')^2+S_j^2-2(S_i-L')S_j dpi=dpj+(SiL)2+Sj22(SiL)Sj
d p j + S j 2 = 2 ( S i − L ′ ) S j + d p i − ( S i − L ′ ) 2 dp_j+S_j^2=2(S_i-L')S_j+dp_i-(S_i-L')^2 dpj+Sj2=2(SiL)Sj+dpi(SiL)2

y = d p j + S j 2 y = dp_j+S_j^2 y=dpj+Sj2 x = S j x=S_j x=Sj k = 2 ( S i − L ′ ) k=2(S_i-L') k=2(SiL) b = d p i − ( S i − L ′ ) 2 b = dp_i-(S_i-L')^2 b=dpi(SiL)2,上式可以写为 y = k x + b y=kx+b y=kx+b

其实这里整理成 d p j + S j 2 + 2 L ′ S j = 2 S i S j + d p i − ( S i − L ′ ) 2 dp_j+S_j^2+2L'S_j=2S_iS_j+dp_i-(S_i-L')^2 dpj+Sj2+2LSj=2SiSj+dpi(SiL)2也可以求解。
只要保证:y、x是只与j相关的表达式,k是与i相关的表达式,b中有 d p i dp_i dpi即可

对于 0 ≤ j < i 0\le j < i 0j<i的所有决策点 ( x , y ) (x, y) (x,y) ( S j , d p j + S j 2 ) (S_j, dp_j+S_j^2) (Sj,dpj+Sj2),看过哪一个决策点的斜率为 k k k的直线的截距 b b b是最小的,此时求出的就是 d p i dp_i dpi的最小值。
接下来进行斜率优化,本文只进行大体描述,具体细节见:
信息学奥赛一本通 1607:【 例 2】任务安排 2 | 洛谷 P10979 任务安排 2
设单调队列q维护所有的决策点集合中的下凸壳。q的队头为 q l q_l ql,队尾为 q r q_r qr
此时随着i的增大, k = 2 ( S i − L ′ ) k=2(S_i-L') k=2(SiL)是增大的,因此对于所有 q l q_l ql q l + 1 q_{l+1} ql+1的斜率 K ( q l , q l + 1 ) K(q_l, q_{l+1}) K(ql,ql+1)满足 K ( q l , q l + 1 ) ≤ 2 ( S i − L ′ ) K(q_l, q_{l+1})\le 2(S_i-L') K(ql,ql+1)2(SiL) q l q_l ql可以进行队头出队。
而后取当前的队头 q l q_l ql作为最优决策点,将 j = q l j=q_l j=ql带入 d p i = d p j + ( S i − S j − L ′ ) 2 dp_i = dp_j+(S_i-S_j-L')^2 dpi=dpj+(SiSjL)2,求出 d p i dp_i dpi,新的决策点为 ( S i , d p i + S i 2 ) (S_i, dp_i+S_i^2) (Si,dpi+Si2)
维护下凸壳,保证没有上凸点,只要 K ( q r , i ) ≤ K ( q r − 1 , q r ) K(q_r, i) \le K(q_{r-1}, q_r) K(qr,i)K(qr1,qr),那么队尾入队i。
最后输出 d p n dp_n dpn

【题解代码】

解法1:斜率优化

#include<bits/stdc++.h>
using namespace std;
typedef long long LL; 
#define N 50005
LL n, L, c[N], s[N], dp[N];//dp[i]::前i个元素的所有子段划分方案中,费用加和最小的方案的费用加和。 
int q[N], l = 1, r = 0;//单调队列
LL Y(int j)
{return dp[j]+s[j]*s[j];
}
LL X(int j)
{return s[j];
}
LL K(int i)
{return 2*(s[i]-L);
}
bool cmp(LL a1, LL b1, LL a2, LL b2)//a1/b1 <= a2/b2
{return a1*b2 <= a2*b1;
}
int main()
{cin >> n >> L;L++;//L'= L+1for(int i = 1; i <= n; ++i){cin >> c[i];s[i] = s[i-1]+c[i]+1;}q[++r] = 0;//dp[0] = 0,添加决策点(s[0], dp[0]+s[0]^2) for(int i = 1; i <= n; ++i){while(l < r && cmp(Y(q[l+1])-Y(q[l]), X(q[l+1])-X(q[l]), K(i), 1))l++;dp[i] = dp[q[l]]+(s[i]-s[q[l]]-L)*(s[i]-s[q[l]]-L);while(l < r && cmp(Y(i)-Y(q[r]), X(i)-X(q[r]), Y(q[r])-Y(q[r-1]), X(q[r])-X(q[r-1])))r--;q[++r] = i;		}cout << dp[n];return 0;
} 

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

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

相关文章

tcping 命令的使用,ping IP 和端口

1. ‌Windows系统安装‌ ‌下载tcping工具‌&#xff1a;根据系统位数&#xff08;32位或64位&#xff09;下载对应的tcping.exe文件。‌安装步骤‌&#xff1a; 将下载的tcping.exe文件复制到C:\Windows\System32目录下。如果下载的是64位版本&#xff0c;需将文件名改为tcpi…

浅谈跨平台框架的演变(H5混合开发->RN->Flutter)

引言 这里分为四个阶段&#xff1a; 第一阶段 &#xff1a; 原生开发 第二阶段 &#xff1a; H5混合开发 第三阶段&#xff1a; 跨平台RN 第四阶段&#xff1a; 跨平台Flutter 正文 第一阶段&#xff1a; 原生开发 开发成本比较大 &#xff1a; 需要Android 和ios 开发两…

《TCP/IP网络编程》学习笔记 | Chapter 20:Windows 中的线程同步

《TCP/IP网络编程》学习笔记 | Chapter 20&#xff1a;Windows 中的线程同步 《TCP/IP网络编程》学习笔记 | Chapter 20&#xff1a;Windows 中的线程同步用户模式和内核模式用户模式同步内核模式同步 基于 CRITICAL_SECTION 的同步内核模式的同步方法基于互斥量对象的同步基于…

力扣45.跳跃游戏

45. 跳跃游戏 II - 力扣&#xff08;LeetCode&#xff09; 代码区&#xff1a; #include<vector> class Solution {public:int jump(vector<int>& nums) {int ans[10005] ;memset(ans,1e4,sizeof(ans));ans[0]0;for(int i0;i<nums.size();i){for(int j1;j…

深入理解 Collections.emptyList():优雅处理空列表的利器!!!

&#x1f680; 深入理解 Collections.emptyList()&#xff1a;优雅处理空列表的利器&#xff01;&#x1f527; 大家好&#xff01;&#x1f44b; 今天我们来聊聊 Java 中一个非常实用但容易被忽视的小工具——Collections.emptyList()。&#x1f389; 如果你经常需要返回一个…

SpringBoot教程(十四) SpringBoot之集成Redis

SpringBoot教程&#xff08;十四&#xff09; | SpringBoot之集成Redis 一、Redis集成简介二、集成步骤 2.1 添加依赖2.2 添加配置2.3 项目中使用之简单使用 &#xff08;举例讲解&#xff09;2.4 项目中使用之工具类封装 &#xff08;正式用这个&#xff09;2.5 序列化 &…

VC6.0图文安装教程

VC6.0图文安装教程 ​ 1、首先&#xff0c;右击安装包&#xff0c;以管理员身份运行 2、点击下一步 ​​​​ 3、点击下一步 4、选择安装路径&#xff0c;点击下一步 5、点击下一步 6、点击安装 7、安装ing 8、点击完成 至此&#xff0c;安装完成&#xff01;

用户说 | 零基础用通义灵码 AI 程序员开发个人笔记网站

作者&#xff1a;宋镇江&#xff0c;安阳幼儿师范高等专科学校数字媒体技术专业教师 通义灵码是一款基于通义大模型的智能编码辅助工具&#xff0c;支持自然语言生成代码、单元测试生成、代码注释生成等功能&#xff0c;兼容多种主流IDE和编程语言。对于零基础用户&#xff0c…

试验一 mybatis 入门操作

试验一 mybatis 入门操作 一 实验目的 1.掌握mybatis基础操作&#xff0c;包括如何在maven工程中引入依赖&#xff0c;创建mapper文件&#xff0c;核心配置文件&#xff0c;映射文件&#xff0c;并测试对数据库表基本的的CRUD操作&#xff1b; 2.掌握核心配置文件中几个重要标…

使用Gitee Go流水线部署个人项目到服务器指南

使用Gitee Go流水线部署个人项目到服务器指南 前言&#xff01;&#xff01;&#xff01; 本文解决的问题&#xff1a; 你有一台ECS服务器&#xff0c;你在上面部署了一个Java服务也就是一个jar&#xff0c;你觉着你每次手动本地打包&#xff0c;上传&#xff0c;在通过命令去…

LCCI ESG 中英联合认证国际分析师适合的岗位

LCCI ESG中英联合认证国际分析师领域热门岗位大揭秘&#xff01;&#x1f30d; 大家好&#xff01;今天我们来探讨LCCI ESG中英联合认证国际分析师领域的热门岗位&#xff0c;看看是否有适合你的选择。 1️⃣ LCCI ESG中英联合认证国际分析师报告专员&#xff1a;主要负责编制…

Compose 实践与探索十五 —— 自定义触摸

1、自定义触摸与一维滑动监测 之前我们在讲 Modifier 时讲过如下与手势检测相关的 Modifier&#xff1a; Modifier.clickable { } Modifier.combinedClickable { } Modifier.pointerInput {detectTapGestures { } }这里对以上内容就不再赘述了&#xff0c;直接去讲解更复杂的…

【Linux】Makefile秘籍

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有问题&#xff0c;还请多多包涵&a…

LDAP从入门到实战:环境部署与配置指南(上)

#作者&#xff1a;朱雷 文章目录 一、LDAP 简介1.1. 什么是目录服务1.2. 什么是 LDAP1.3. LDAP的基本模型 二、Ldap环境部署2.1.下载软件包2.2.安装软件2.3.编辑配置文件2.4.启动服务 一、LDAP 简介 1.1. 什么是目录服务 目录是专门为搜索和浏览而设计的专用数据库&#xff…

《C++智能指针:建议使用 make_shared 代替 shared_ptr》

《C 智能指针&#xff1a;长达数十年的血泪史&#xff0c;一步步征服内存泄漏》-CSDN博客 shared_ptr<int> sp1(new int(10)); 这句代码实际存在两个内存开辟&#xff0c;一是开辟我们要托管的内存资源 &#xff0c;二是开辟引用计数的资源&#xff0c;引用技术也是new出…

代码随想录刷题day50|(回溯算法篇)131.分割回文串▲

目录 一、回溯算法基础知识 二、分割回文串思路 2.1 如何切割 2.2 判断回文 2.3 回溯三部曲 2.4 其他问题 三、相关算法题目 四、总结 一、回溯算法基础知识 详见&#xff1a;代码随想录刷题day46|&#xff08;回溯算法篇&#xff09;77.组合-CSDN博客 二、分割回文…

vivo 湖仓架构的性能提升之旅

作者&#xff1a;郭小龙 vivo互联网 大数据高级研发工程师 导读&#xff1a;本文整理自 vivo互联网 大数据高级研发工程师 郭小龙 在 StarRocks 年度峰会上的分享&#xff0c;聚焦 vivo 大数据多维分析面临的挑战、StarRocks 落地方案及应用收益。 在 即席分析 场景&#xff0c…

Springboot的jak安装与配置教程

目录 Windows系统 macOS系统 Linux系统 Windows系统 下载JDK&#xff1a; 访问Oracle官网或其他JDK提供商网站&#xff0c;下载适合Windows系统的JDK版本。网站地址&#xff1a;Oracle 甲骨文中国 | 云应用和云平台点击进入下滑&#xff0c;点击进入下载根据自己的系统选择&…

力扣算法Hot100——128. 最长连续序列

题目要求时间复杂度为O(n)&#xff0c;因此不能使用两次循环匹配。 首先使用 HashSet 去重&#xff0c;并且 HashSet 查找一个数的复杂度为O(1)外循环还是遍历set集合&#xff0c;里面一重循环需要添加判断&#xff0c;这样才不会达到O( n 2 n^2 n2)判断是否进入最长序列查找循…

BlockChain.java

BlockChain 区块链&#xff0c;举个栗子 注意啦&#xff0c;列子里面的hashcode相等&#xff0c;但是字符串是不一样的哦&#xff0c;之前有记录这个问题 String.hashCode()-CSDN博客