[APIO2010]特别行动队
题目描述
你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 n 编号,要将他们拆分 成若干特别行动队调入战场。出于默契的考虑,同一支特别行动队中队员的编号 应该连续,即为形如(i, i + 1, ..., i + k)(i,i+1,...,i+k)的序列。 编号为 i 的士兵的初始战斗力为 xi ,一支特别行动队的初始战斗力 x 为队内 士兵初始战斗力之和,即 x = x_i + x_{i+1} + ... + x_{i+k}x=xi+xi+1+...+xi+k。
通过长期的观察,你总结出一支特别行动队的初始战斗力 x 将按如下经验公 式修正为 x':x'= ax^2+bx+cx′:x′=ax2+bx+c,其中 a, b, c 是已知的系数(a < 0)。 作为部队统帅,现在你要为这支部队进行编队,使得所有特别行动队修正后 战斗力之和最大。试求出这个最大和。
例如,你有 4 名士兵, x_1 = 2, x_2 = 2, x_3 = 3, x_4 = 4x1=2,x2=2,x3=3,x4=4。经验公式中的参数为 a = –1, b = 10, c = –20。此时,最佳方案是将士兵组成 3 个特别行动队:第一队包含士兵 1 和士兵 2,第二队包含士兵 3,第三队包含士兵 4。特别行动队的初始战斗力分 别为 4, 3, 4,修正后的战斗力分别为 4, 1, 4。修正后的战斗力和为 9,没有其它 方案能使修正后的战斗力和更大。
网上对斜率优化的解释太玄乎,我看不懂,所以用自己的方法来解释一下斜率优化:
所谓斜率优化,优化的是DP【i】=max(min)(C(i)+C(j)+K(j)*S(i))的dp方程
其中C(i)是只跟i有关的常数,c(j)是和j有关的常数,K(j)和S(i)是分别与ij有关的函数。
整理 得 DP【i】-C(i)=K(j)*S(i)+C(j),我们只要求K(j)*S(i)+C(j)的最值即可。
我们发现每一个J代表一条直线,其自变量为S(i),且S(i)单调递增。
那么我们可以动态的维护一个直线的集合,其K依次递增,C依次递减。(当存在一条直线的K,C都比另一条小时,那它就永远不会成为最优解)。
又因为K依次递增,C依次递减,而且S(i)单调递增,那么一条直线被他后面的直线追上后,就一直比被其追上的直线小了。(两线一交点)。
那么我们就可以这样来维护一个单调队列来优化DP了吗?
答案是否定的。
我们发现了反例。
我们考虑三条直线,y1=10,y2=X+9,y3=100x+1.
显然这三条直线在单调队列中是合法的。
但我们发现 y1和y2的交点在X=1处,y1与y3的交点却在X=0.09处。
按照我们刚才的做法,当X=0.5时,我们还是误以为y1是当前的最优直线,但事实上是y3最优。
所以我们在队尾加入直线时,要判当前要加的直线与前一条直线与前一条直线的前一条直线的交点哪一个在前,如果当前直线的交点在前的话,那就可以将队尾的直线弹出了,因为它已经没有机会成为最优解了。
#include<bits/stdc++.h>
#define B(x) (1ll*a*sum[x]*sum[x]+dp[x]-b*sum[x])//就是题解里的C(j),直线的截距,y=kx+b中的b
#define K(x) (-2ll*a*sum[x])//直线的斜率
#define N 1070001
#define LL long long
#define sight(C) (C<='9'&&C>='0')
using namespace std;
LL sum[N],q[N],n,m,x,head,tail,dp[N],a,b,c;
LL check(int x,int y) {//判断当前直线与i组合的DP值
return dp[y]+a*(sum[x]-sum[y])*(sum[x]-sum[y])+b*(sum[x]-sum[y])+c;
} char C;int B;
double jiao(int x,int y){ //求直线的交点
return 1.0*(B(x)-B(y))/(K(x)-K(y));
}
LL read(LL &x) {
C=getchar(); B=;
for(;!sight(C);C=getchar()) if (C=='-') B=-;
for(x=;sight(C);C=getchar()) x=x*+C-'';
x*=B;
}
int main () {
read(n);
read(a); read(b); read(c);
for (int i=;i<=n;i++)
read(x),sum[i]=sum[i-]+x;
head=tail=;
q[tail++]=;
for (int i=;i<=n;i++) {
while (head+<tail && check(i,q[head])<=check(i,q[head+])) head++;//当前解被超过,将其出队
dp[i]=check(i,q[head]);
while (head+<tail && jiao(q[tail-],i)<=jiao(q[tail-],i)) tail--;//i与q【tail-1】相比,i的交点在前,所以将q【tail-1】删除
q[tail++]=i;
}
printf("%lld\n",dp[n]);
return ;
}
[APIO2010]特别行动队的更多相关文章
- BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 4142 Solved: 1964[Submit][Statu ...
- 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)
dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...
- bzoj 1911 [Apio2010]特别行动队(斜率优化+DP)
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3191 Solved: 1450[Submit][Statu ...
- BZOJ 1911: [Apio2010]特别行动队( dp + 斜率优化 )
sum为战斗力的前缀和 dp(x) = max( dp(p)+A*(sumx-sump)2+B*(sumx-sump)+C )(0≤p<x) 然后斜率优化...懒得写下去了... ------- ...
- bzoj1911[Apio2010]特别行动队 斜率优化dp
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 5057 Solved: 2492[Submit][Statu ...
- P3628 [APIO2010]特别行动队(斜率优化dp)
P3628 [APIO2010]特别行动队 设$s[i]$为战斗力前缀和 显然我们可以列出方程 $f[i]=f[j]+a*(s[i]-s[j])^{2}+b*(s[i]-s[j])+c$ $f[i]= ...
- [luogu P3628] [APIO2010]特别行动队
[luogu P3628] [APIO2010]特别行动队 题目描述 你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 n 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑,同一支特 ...
- 【bzoj1911】[Apio2010]特别行动队
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 4048 Solved: 1913[Submit][Statu ...
- [APIO2010]特别行动队 --- 斜率优化DP
[APIO2010]特别行动队 题面很直白,就不放了. 太套路了,做起来没点感觉了. \(dp(i)=dp(j)+a*(s(i)-s(j))^{2}+b*(s(i)-s(j))+c\) 直接推出一个斜 ...
- bzoj 1911: [Apio2010]特别行动队 -- 斜率优化
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MB Description Input Output Sample Input 4 ...
随机推荐
- mysql实现full join
呵呵,,,有个坑,,mysql默认不支持full join 是吧. 什么是full join呢就是left+right join 可以使用union联表解决这个问题 union 链接 http:// ...
- Openssl 生成证书server.key and server.crt
1.key的生成 openssl genrsa -des3 -out server.key 2048 这样是生成rsa私钥,des3算法,openssl格式,2048位强度.server.key是密钥 ...
- YiShop_最全微信营销涨粉技巧
在我们开始推广企业订阅号之前,我们必须思考微信营销策略,客户通过微信可以获得什么?企业通过微信可以得到什么?微分销专家建议企业微信定位为互动.服务工具,因为获取一个粉丝很难,可是失去一个粉丝,却是一件 ...
- 用 Label 控制 Service 的位置 - 每天5分钟玩转 Docker 容器技术(106)
上一节我们讨论了 Service 部署的两种模式:global mode 和 replicated mode.无论采用 global mode 还是 replicated mode,副本运行在哪些节点 ...
- 》》mui--图片轮播
mui框架内置了图片轮播插件,通过该插件封装的JS API,用户可以设定是否自动轮播及轮播周期,如下为代码示例: //获得slider插件对象 var gallery = mui('.mui-slid ...
- Excel大写和小写转换函数
Excel中的大写和小写转换函数 (1).转换为所有小写字母:lower函数 (2).转换为所有大写字母:upper函数 (3).转换为首字母大写,其余小写字母:proper函数 三种函数的使用方式. ...
- 【Notification】屏蔽特定应用的通知提示
须要默认屏蔽特定app的通知提示 设置app是否接收通知的界面 点击每一个条目进去的界面 AppNotificationSettings extends SettingsPreferenceFragm ...
- [Shell]crontab 运行任务调用shell脚本,相对路径无法找到
问题出现的场景大概就是 1 cron调用一个python脚本 2 python脚本中调用一个shell脚本(对日志分析)获取shell输出然后发送邮件 类似一个监控任务. 直接运行python脚本 ...
- JQuery插件开发标准写法
;//step01 定义JQuery的作用域 (function ($) { //step03-a 插件的默认值属性 var defaults = { prevId: 'prevBtn', prevT ...
- 从0开始做垂直O2O个性化推荐-以58到家美甲为例
从0开始做垂直O2O个性化推荐 上次以58转转为例,介绍了如何从0开始如何做互联网推荐产品(回复"推荐"阅读),58转转的宝贝为闲置物品,品类多种多样,要做统一的宝贝画像比较难,而 ...