Description

Link.

给出 \(N\) 个单词,每个单词有个非负权值 \(C_{i}\),现要将它们分成连续的若干段,每段的代价为此段单词的权值和,还要加一个常数 \(M\),即 \((\sum C_{i})^{2}+M\)。现在想求出一种最优方案,使得总费用之和最小

Solution

设 \(f_{i}\) 表示 \(n=i\) 时的答案,转移方程为:

\[f_{i}=\min\{f_{j}+S_{i..j}^{2}+M\}
\]

显然过不了,推成可以斜率优化的形式。

我们假设决策 \(j\) 优于决策 \(k\) 且 \(k<j<i\)。

(一种错误的思路)

\[f_{j}+S_{i..j}^{2}+M<f_{k}+S_{i..k}^{2}+M
\]
\[f_{j}+(S_{i}-S_{j})^{2}<f_{k}+(S_{i}-S_{k})^2
\]
\[f_{j}+S_{i}^2-2S_{i}S_{j}+S_{j}^{2}<f_{k}+S_{i}^2-2S_{i}S_{k}+S_{k}^{2}
\]
\[f_{j}-2S_{i}S_{j}+S_{j}^{2}<f_{k}-2S_{i}S_{k}+S_{k}^{2}
\]
\[f_{j}-2S_{i}S_{j}+2S_{i}S_{k}+S_{j}^{2}-S_{k}^{2}-f_{k}<0
\]
\[f_{j}-2S_{i}(S_{j}+ S_{k})+(S_{j}-S_{k})(S_{j}+S_{k})-f_{k}<0
\]
\[f_{j}-(S_{j}+ S_{k})(2S_{i}+S_{j}-S_{k})-f_{k}<0
\]
\[f_{j}-\frac{S_{j}+ S_{k}}{2S_{i}+S_{j}-S_{k}}-f_{k}<0
\]

最后发现做 \(\text{TM}\) 不出来。

于是重新推:

(另一种错误思路)(我简直自闭)

\[f_{j}+S_{i..j}^{2}+M<f_{k}+S_{i..k}^{2}+M
\]
\[f_{j}+(S_{i}-S_{j})^{2}<f_{k}+(S_{i}-S_{k})^2
\]
\[f_{j}+S_{i}^2-2S_{i}S_{j}+S_{j}^{2}<f_{k}+S_{i}^2-2S_{i}S_{k}+S_{k}^{2}
\]
\[f_{j}-2S_{i}S_{j}+S_{j}^{2}<f_{k}-2S_{i}S_{k}+S_{k}^{2}
\]
\[f_{j}-f_{k}+S_{j}^{2}-S_{k}^{2}<2S_{i}S_{j}-2S_{i}S_{k}
\]
\[f_{j}-f_{k}+S_{j}^{2}-S_{k}^{2}<2S_{i}(S_{j}-S_{k})
\]
\[f_{j}-f_{k}+(S_{j}-S_{k})(S_{j}+S_{k})<2S_{i}(S_{j}-S_{k})
\]
\[\frac{f_{j}-f_{k}}{2(S_{j}-S_{k})}+\frac{S_{j}+S_{k}}{2}<S_{i}
\]

嗯,还是 \(\text{TM}\) 做不来。

好了,推倒重来。

(这次是对的)

\[f_{i}=\min\{f_{j}+S_{i..j}^{2}+M\}
\]
\[f_{j}+S_{i..j}^{2}+M<f_{k}+S_{i..k}^{2}+M
\]
\[f_{j}+(S_{i}-S_{j})^{2}<f_{k}+(S_{i}-S_{k})^2
\]
\[f_{j}+S_{i}^2-2S_{i}S_{j}+S_{j}^{2}<f_{k}+S_{i}^2-2S_{i}S_{k}+S_{k}^{2}
\]
\[f_{j}-2S_{i}S_{j}+S_{j}^{2}<f_{k}-2S_{i}S_{k}+S_{k}^{2}
\]
\[f_{j}-f_{k}+S_{j}^{2}-S_{k}^{2}<2S_{i}S_{j}-2S_{i}S_{k}
\]
\[f_{j}-f_{k}+S_{j}^{2}-S_{k}^{2}<2S_{i}(S_{j}-S_{k})
\]
\[\frac{(f_{j}+S_{j}^{2})-(f_{k}+S_{k}^{2})}{2(S_{j}-S_{k})}<S_{i}
\]

我们令 \(Y_{i}=f_{i}+S_{i}^{2}\),\(X_{i}=2S_{i}\),则我们有:

\[\frac{Y_{j}-Y_{k}}{X_{j}-X_{k}}<S_{i}
\]

挺好的,正好就是斜率优化的形式!

斜率优化!

牛逼啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎哎啊啊哎。

那么接下来我们设 \(F(j,k)=\frac{Y_{j}-Y_{k}}{X_{j}-X_{k}}\)。

其中如果满足 \(F(j,k)<S_{i}\),则我们称决策 \(j\) 优于决策 \(k\)。

现在我们继续设 \(k<j<i\),那么如果满足 \(F(i,j)<F(j,k)\),决策 \(j\) 就永远不可能成为最优解。

证明不会,\(\text{PPT}\) 没看懂。

最后放个 \(\text{PPT}\) 里写的 \(\text{Summary}\):

1、用一个单调队列来维护解集。

2、假设队列中从头到尾已经有元素 \(a\),\(b\),\(c\)。那么当 \(d\) 要入队的时候,维护队列的上凸性质,即如果 \(F(d,c)<F(c,b)\),那么删除点 \(c\)。直到找到 \(F(d,x)\ge F(x,y)\) 为止,并将 \(d\) 点加入在该位置中。

3、求解的时候,从对头开始,如果已有元素 \(a\),\(b\),\(c\),当 \(i\) 点要求解时,如果 \(F(b,a)<S_{i}\),说明 \(b\) 点比 \(a\) 点更优,\(a\) 点直接排除,于是 \(a\) 出队,最后 \(f_{i} = \mathrm{getDp}(Q[\mathrm{head}])\)。

#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long LL; namespace MySpace
{
template<class _T>
void read(_T &x)
{
x = 0;
char c = getchar();
_T f = 1;
while( c < '0' || c > '9' )
{
if( c == '-' ) f = -1;
if( c == -1 ) exit( 0 );
c = getchar();
}
while( c >= '0' && c <= '9' ) x = x * 10 + c - '0', c = getchar();
x *= f;
} template<class _T>
void write(_T x)
{
if( x < 0 ) putchar( '-' ), x = -x;
if( x > 9 ) write( x / 10 );
putchar( x % 10 + '0' );
} const LL MAXN = 5e5 + 5;
LL N, M, Dp[MAXN], Q[MAXN], S[MAXN], A[MAXN]; LL Square( LL x ) { return x * x; }
LL Up( LL i ) { return Dp[i] + Square( S[i] ); }
LL Down( LL i ) { return S[i] << 1; }
LL FracUp( LL j, LL k ) { return Up( j ) - Up( k ); }
LL FracDown( LL j, LL k ) { return Down( j ) - Down( k ); }
} int main()
{
using namespace MySpace;
while( ~ scanf( "%lld%lld", &N, &M ) )
{
for( LL i = 1; i <= N; ++ i ) scanf( "%lld", &A[i] ), S[i] = S[i - 1] + A[i];
LL l = 1, r = 1;
Q[r] = 0;
for( LL i = 1; i <= N; ++ i )
{
while( l < r && FracUp( Q[l + 1], Q[l] ) < S[i] * FracDown( Q[l + 1], Q[l] ) ) l ++;
Dp[i] = Dp[Q[l]] + Square( S[i] - S[Q[l]] ) + M;
while( l < r && FracUp( i, Q[r] ) * FracDown( Q[r], Q[r - 1] ) <= FracUp( Q[r], Q[r - 1] ) * FracDown( i, Q[r] )) r --;
Q[++ r] = i;
}
printf( "%lld\n", Dp[N] );
}
// while( read( N ), read( M ), 1 )
// {
// for( LL i = 1; i <= N; ++ i ) read( A[i] ), S[i] = S[i - 1] + A[i];
// LL l = 1, r = 0;
// Q[l] = 0;
// for( LL i = 1; i <= N; ++ i )
// {
// while( l <= r && FracUp( Q[l + 1], Q[l] ) < S[i] * FracDown( Q[l + 1], Q[l] ) ) l ++;
// Dp[i] = Dp[Q[l]] + Square( S[i] - S[Q[l]] ) + M;
// while( l <= r && FracUp( i, Q[r - 1] ) * FracDown( Q[r - 1], Q[r - 2] ) < FracUp( Q[r - 1], Q[r - 2] ) * FracDown( i, Q[r - 1] )) r ++;
// Q[++ r] = i;
// }
// write( Dp[N] ), putchar( '\n' );
// }
return 0;
}

Solution -「HDU 3507」Print Article的更多相关文章

  1. Solution -「HDU 6875」Yajilin

    \(\mathcal{Description}\)   Link.(HDU 裂开了先放个私链 awa.)   在一个 \(n\times n\) 的方格图中,格子 \((i,j)\) 有权值 \(w_ ...

  2. Solution -「HDU 5498」Tree

    \(\mathcal{Description}\)   link.   给定一个 \(n\) 个结点 \(m\) 条边的无向图,\(q\) 次操作每次随机选出一条边.问 \(q\) 条边去重后构成生成 ...

  3. Solution -「HDU 6643」Ridiculous Netizens

    \(\mathcal{Description}\)   Link.   给定一棵含有 \(n\) 个结点的树,点 \(u\) 有点权 \(w_u\),求树上非空连通块的数量,使得连通块内点权积 \(\ ...

  4. Solution -「HDU 1788」CRT again

    \(\mathcal{Description}\)   Link.   解同余方程组: \[x\equiv m_i-a\pmod{m_i} \]   其中 \(i=1,2,\dots,n\).   \ ...

  5. Solution -「HDU #6566」The Hanged Man

    \(\mathcal{Description}\)   Link.   给定一棵含 \(n\) 个点的树,每个结点有两个权值 \(a\) 和 \(b\).对于 \(k\in[1,m]\),分别求 \[ ...

  6. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  7. Solution -「HDU」Professor Ben

    Description 有 \(Q\) 个询问.每次给定一个正整数 \(n\),求它的所有因数的质因数个数的和. Solution 就讲中间的一个 Trick. 我们定义正整数 \(x\) 有 \(f ...

  8. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  9. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

  10. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

随机推荐

  1. Spring配置动态数据库

    前言 本文主要介绍使用spring boot 配置多个数据库,即动态数据库 开始搭建 首先创建一个SpringWeb项目--dynamicdb(spring-boot2.5.7) 然后引入相关依赖lo ...

  2. CKS 考试题整理 (09)-日志审计 log audit

    Task 在cluster中启用审计日志.为此,请启用日志后端,并确保: 日志存储在 /var/log/kubernetes/audit-logs.txt 日志文件能保留 10 天 最多保留 2 个旧 ...

  3. C#语言async, await 简单介绍与实例(入门级)

    本文介绍异步编程的基本思想和语法.在程序处理里,程序基本上有两种处理方式:同步和异步.对于有些新手,甚至认为"同步"是同时进行的意思,这显然是错误的. 同步的基本意思是:程序一个个 ...

  4. 前端树形结构图treeShapeStruct,可拖拽移动,点击展开收缩,无限添加子集

    快速实现树形结构图,可拖拽移动,点击展开收缩,无限添加子集; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12650 效果图如 ...

  5. AI室内设计:提升效率、消除沟通障碍,满足客户需求

    前言 免费AI绘图工具:https://www.topgpt.one 随着人工智能(AI)技术的不断发展,室内设计行业也开始受益于这一技术的应用.其中,AI绘画工具在室内设计中的应用正日益受到关注.这 ...

  6. 详解Django请求与响应:深入理解Web Http交互的核心机制

    本文深入探讨了 Django 中的请求与响应处理,从 Django 请求和响应的基础知识.生命周期,到 HttpRequest 和 HttpResponse 对象的详细介绍.同时,讨论了 Django ...

  7. 【Python】数据可视化利器PyCharts在测试工作中的应用

    PyCharts 简介 PyCharts 是一个基于 Python 的数据可视化库,它支持多种图表类型,如折线图.柱状图.饼图等.PyCharts 提供了简洁的 API,使得用户能够轻松地创建各种图表 ...

  8. Hexo博客Next主题添加粒子时钟特效

    博客应用canvas粒子时钟的操作步骤: 在\themes\next\layout\_custom\目录下,新建clock.swig文件,内容如下: <div style="" ...

  9. Map集合_HashMap_TreeMap_等_小记

    Map是一种依照键值对数据存储元素的容器. Map中的元素是两个对象,一个对象作为键,一个对象作为值.一个键(key)和它对应的值构成map集合中的一个元素.Map集合的数据结构只跟键有关,键不可以重 ...

  10. Centos7中Jar快速启动脚本

    Centos7中Jar快速启动脚本 创建一个文本,将以下脚本内容复制到文本当中,重命名文本后缀为.sh 注意:根据自己的项目进行更改相关内容,对应注释已说明 #!/bin/sh APP_NAME=ma ...