当前位置: 首页 > wzjs >正文

合肥网站设计建佛山专业网站开发公司

合肥网站设计建,佛山专业网站开发公司,免费做网站公司哪家好,网站建设与网页设计考试题写了挺多斜率优化的题目了,这道(差点)就速切了,原因还是单调队列维护斜率的写法出锅。 题意 题目描述 你正在玩一个关于长度为 n n n 的非负整数序列的游戏。这个游戏中你需要把序列分成 k 1 k 1 k1 个非空的块。为了得到 …

写了挺多斜率优化的题目了,这道(差点)就速切了,原因还是单调队列维护斜率的写法出锅。

题意

题目描述

你正在玩一个关于长度为 n n n 的非负整数序列的游戏。这个游戏中你需要把序列分成 k + 1 k + 1 k+1 个非空的块。为了得到 k + 1 k + 1 k+1 块,你需要重复下面的操作 k k k 次:

选择一个有超过一个元素的块(初始时你只有一块,即整个序列)

选择两个相邻元素把这个块从中间分开,得到两个非空的块。

每次操作后你将获得那两个新产生的块的元素和的乘积的分数。你想要最大化最后的总得分,并知道得到最大总分的方案。

如果有多种方案使得总得分最大,输出任意一种方案即可。

输入

7 3
4 1 3 4 0 2 3

输出

108
1 3 5

2 ≤ n ≤ 100000 , 1 ≤ k ≤ min ⁡ { n − 1 , 200 } 2 \leq n \leq 100000, 1 \leq k \leq \min\{n - 1, 200\} 2n100000,1kmin{n1,200}

思路

对序列分割,分割的顺序会不会对答案造成影响呢?

之前 smsky 选拔的时候,第一题与之是类似的。我们可以猜测:对于这种大块的乘积,如果固定了分割点,无论分割顺序如何,都不会改变结果

考虑简要地证明这个结论:设序列有三个分割点 1 , 2 , 3 1,2,3 1,2,3,序列被分割成了元素和依次为 a , b , c , d a,b,c,d a,b,c,d 的四块。

  • 1 , 2 , 3 1,2,3 1,2,3 的顺序分割: a n s 1 = a ( b + c + d ) + a ( b + c ) + c d = a b + a c + a d + b c + b d + c d ans_1=a(b+c+d)+a(b+c)+cd=ab+ac+ad+bc+bd+cd ans1=a(b+c+d)+a(b+c)+cd=ab+ac+ad+bc+bd+cd
  • 3 , 1 , 2 3,1,2 3,1,2 的顺序分割: a n s 2 = ( a + b + c ) d + a ( b + c ) + b c = a d + b d + c d + a b + a c + b c ans_2=(a+b+c)d+a(b+c)+bc=ad+bd+cd+ab+ac+bc ans2=(a+b+c)d+a(b+c)+bc=ad+bd+cd+ab+ac+bc;
  • 1 , 3 , 2 1,3,2 1,3,2 的顺序分割:。。。

多枚举几组,我们发现 a n s ans ans 始终不变。

因此简证成立。

那么我们就可以 1 ∼ n 1\sim n 1n 枚举分割点了。考虑朴素的 dp,设 f i , t f_{i,t} fi,t 表示前 i i i 个数,分割了 t t t 次,且在 i i i 之后不分割的最小花费。(这样子就不用特意讨论 n n n 之后还被分割了的情况了)

处理前缀和 p r e i = ∑ j = 1 i a j pre_i=\sum_{j=1}^{i}a_j prei=j=1iaj。枚举分割点 j j j,在 1 ∼ i 1\sim i 1i 分成了 1 ∼ j 1\sim j 1j j + 1 ∼ i j+1\sim i j+1i 两块,和分别是:
f i , t = max ⁡ j = 1 i − 1 { f j , t − 1 + p r e j ( p r e i − p r e j ) } f_{i,t}=\max_{j=1}^{i-1}\left\{f_{j,t-1}+pre_j(pre_i-pre_j)\right\} fi,t=j=1maxi1{fj,t1+prej(preiprej)}

设两个决策点 j 1 < j 2 j1<j2 j1<j2 j 2 j2 j2 优于 j 1 j1 j1,那么:
f j 1 , t − 1 + p r e j 1 ( p r e i − p r e j 1 ) < f j 2 , t − 1 + p r e j 2 ( p r e i − p r e j 2 ) f_{j1,t-1}+pre_{j1}(pre_i-pre_{j1})<f_{j2,t-1}+pre_{j2}(pre_i-pre_{j2}) fj1,t1+prej1(preiprej1)<fj2,t1+prej2(preiprej2)

f j 1 , t − 1 + p r e i p r e j 1 − p r e j 1 2 ) < f j 2 , t − 1 + p r e i p r e j 2 − p r e j 2 2 f_{j1,t-1}+pre_ipre_{j1}-pre_{j1}^2)<f_{j2,t-1}+pre_ipre_{j2}-pre_{j2}^2 fj1,t1+preiprej1prej12)<fj2,t1+preiprej2prej22

f j 1 , t − 1 − f j 2 , t − 1 + p r e j 2 2 − p r e j 1 2 < p r e i ( p r e j 2 − p r e j 1 ) f_{j1,t-1}-f_{j2,t-1}+pre_{j2}^2-pre_{j1}^2<pre_i(pre_{j2}-pre_{j1}) fj1,t1fj2,t1+prej22prej12<prei(prej2prej1)

注意到 p r e j 2 − p r e j 1 ≥ 0 pre_{j2}-pre_{j1}\ge 0 prej2prej10,依旧注意避开 0 0 0;如果非 0 0 0 就可以直接除过去:
f j 1 , t − 1 − f j 2 , t − 1 + p r e j 2 2 − p r e j 1 2 p r e j 2 − p r e j 1 < p r e i \frac{f_{j1,t-1}-f_{j2,t-1}+pre_{j2}^2-pre_{j1}^2}{pre_{j2}-pre_{j1}}<pre_i prej2prej1fj1,t1fj2,t1+prej22prej12<prei

s l o p e < p r e i slope<pre_i slope<prei p r e i pre_i prei 单增,和玩具装箱是同一类,维护单调递增斜率,最优决策扔队首就好。

因为还有一个切割次数的维度,所以可以对每一次切割 t ∈ [ 1 , k ] t\in[1,k] t[1,k],每次 t + 1 ← t t+1\leftarrow t t+1t 转移的时候做一次斜率优化 dp 即可。

题目还有一个要求就是求切割的方案,那也很好做,就是记录前缀数组 f a t i , t fat_{i,t} fati,t 表示枚举到 i i i,切割了 t t t 次的第 t t t 次切割点。由于单调队列直接维护反馈的就是最优决策点,那么用 f a t fat fat 数组记录每次的队首就好。

有一点要注意,因为 f a t fat fat 数组与单调队列维护的最优决策点挂钩,那么单调队列应当严谨维护。在上一篇题解,弹出队尾时时要写 ≤ \le 之外,还要把队首往后压,防止出现 0 0 0 的情况(其实就是把推式子的时候,把两个决策点 j 1 j1 j1 j 2 j2 j2 之间的符号改成 ≤ \le ,对答案 1 1 1 正确性没有影响,但是缩减了很多不必要的 0 0 0 决策点)

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define dd double
const ll N=1e5+9,K=202,inf=0x7f7f7f7f;
ll n,k,a[N];
ll f[N][K],q[N],pre[N];
int fat[N][K];
ll _2(ll x)
{return x*x;
}
dd slope(ll j1,ll j2,ll t)
{if(pre[j1]==pre[j2])return -inf;return (dd)(f[j1][t-1]-f[j2][t-1]+_2(pre[j2])-_2(pre[j1]))/(dd)(pre[j2]-pre[j1]);
}
int main()
{scanf("%lld%lld",&n,&k);for(int i=1;i<=n;i++){scanf("%lld",&a[i]);pre[i]=pre[i-1]+a[i];}for(int t=1;t<=k;t++){ll hh=0,tt=0;for(int i=1;i<=n;i++){while(hh<tt&&slope(q[hh],q[hh+1],t)<=pre[i])hh++;f[i][t]=f[q[hh]][t-1]+pre[q[hh]]*(pre[i]-pre[q[hh]]);fat[i][t]=q[hh];while(hh<tt&&slope(q[tt],i,t)<=slope(q[tt-1],q[tt],t))tt--;q[++tt]=i;}}printf("%lld\n",f[n][k]);for(int tem=n,i=k;i>=1;i--){tem=fat[tem][i];printf("%d ",tem);}return 0;
}
http://www.dtcms.com/wzjs/573196.html

相关文章:

  • 网络工程师 网站建设灵动网站建设
  • 怎么用h5做网站网站规划与建设是什么意思
  • 海口专门做网站广告设计公司有哪些
  • 娱乐网站建设郑州网站推广哪家专业
  • 网站后台管理界面代码做设计哪个网站可以接单
  • 易企营销型网站建设企业wordpress打开失败
  • 西安哪有学做淘宝网站如何做微信电子书下载网站
  • IC 网站建设制作网页软件app
  • 版本设计网站米拓建站模板
  • 衡水建网站北京网站定制建设
  • 网站网站建站红塔网站制作
  • 佛山市网站建设分站多少钱服务型网站建设
  • 万户网站天下ai做图标教程网站
  • 网站如何注销苏州做网站优化的
  • 用cdr做网站设计尺寸要多少wordpress 自动图片大小
  • 山东青岛网站设计公司百度关键词搜索排名多少钱
  • 动态商务网站开发与管理中信建设有限责任公司深圳中信金融中心项目工期专业招标
  • 免费的网站域名查询浏览器群排名优化软件官网
  • 微网站建设教程视频上海建设工程网
  • php做简单网站教程视频教程网站子目录
  • 创建一个网站需要什么海东高端网站建设价格
  • 有什么方法在淘宝发布网站建设设计赣州网站建设设计
  • 创建网站投资多少环保网站建设价格
  • 建手机网站款软件网站建设支付方式
  • dede后台做两个网站办公室设计公司专业网站
  • 高端网站建设企业国内永久免费的crm系统软件
  • 个人网站怎么样的1g1m wordpress
  • 深圳网站建设找哪家公司开贴纸网站要怎么做
  • 启航网站管理系统项目管理网站开发
  • 网站建设 业务培训昆明哪些做网站建设的公司