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. 大家听过Java applet吗?为什么不再流行了

    前言 Java applet 不知道有同学听过吗?我也只是听过,并没有使用过.我特意去了解了一下它,本文就对 Java applet 进行简单介绍,说说它的辉煌与衰败.仅此而已,现在已经没人使用 Ja ...

  2. 20个Golang片段让我不再健忘

    前言 本文使用代码片段的形式来解释在 go 语言开发中经常遇到的小功能点,由于本人主要使用 java 开发,因此会与其作比较,希望对大家有所帮助. 1. hello world 新手村的第一课,毋庸置 ...

  3. App性能测试之iTest

    本文主要介绍下App性能测试工具iTest_V4.7的使用. 功能简介 1.监控Andorid系统(支持手机,平板,电视,车机等智能终端设备)以及应用app的cpu.内存.流量.电池.帧率.页面耗时等 ...

  4. 识别一切模型RAM(Recognize Anything Model)及其前身 Tag2Text 论文解读

    总览 大家好,我是卷了又没卷,薛定谔的卷的AI算法工程师「陈城南」~ 担任某大厂的算法工程师,带来最新的前沿AI知识和工具,欢迎大家交流~ 继MetaAI 的 SAM后,OPPO 研究院发布识别一切模 ...

  5. O2OA(翱途)开发平台如何在流程表单中使用基于Vue的ElementUI组件?

    本文主要介绍如何在O2OA中进行审批流程表单或者工作流表单设计,O2OA主要采用拖拽可视化开发的方式完成流程表单的设计和配置,不需要过多的代码编写,业务人员可以直接进行修改操作. 在流程表单设计界面, ...

  6. SpringBoot 如何优雅的进行全局异常处理?

    在SpringBoot的开发中,为了提高程序运行的鲁棒性,我们经常需要对各种程序异常进行处理,但是如果在每个出异常的地方进行单独处理的话,这会引入大量业务不相关的异常处理代码,增加了程序的耦合,同时未 ...

  7. 2023-07-13:如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。 花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串 定义下面几条语

    2023-07-13:如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串. 花括号展开的表达式可以看作一个由 花括号.逗号 和 小写英文字母 组成的字符串 定义下面几条语 ...

  8. you-get的使用

    转载自: 利用Python下载:You-Get的安装及使用方法 - 宁佳兵 - 博客园   宁佳兵 所谓的光辉岁月,并不是后来闪耀的日子,而是无人问津时,对梦想的偏执. 博客园 首页 标签 GitHu ...

  9. Python数据分析易错知识点归纳(六):机器学习

    六.机器学习 分类和聚类的区别 分类是有监督学习,聚类是无监督学习 分类算法用于预测新样本,聚类用于理解已知数据 标准化/归一化 type_se_num = type_se[type_se!= 'ob ...

  10. 基于GPT搭建私有知识库聊天机器人(六)仿chatGPT打字机效果

    文章链接: 基于GPT搭建私有知识库聊天机器人(一)实现原理 基于GPT搭建私有知识库聊天机器人(二)环境安装 基于GPT搭建私有知识库聊天机器人(三)向量数据训练 基于GPT搭建私有知识库聊天机器人 ...