Gym - 101806R :Recipe(分治+斜率优化)
题意:有一个厨师,他买菜-做菜-买菜-做菜....-做菜,一共有N天,他的冰箱里只能有一个菜,在他做菜的第二天才会买菜,如果菜不做,放在冰箱里,每天新鲜程度会下降1。 第一天也会买菜,第i天的菜新鲜程度的Fi,厨艺是Ci,(厨艺会增长),要求这一天做的菜的新鲜长度大于等于Li。
思路:即dpi=max dp[j]+[F[j+1]-(i-(j+1))]*Ci (满足Li>=F[j+1]-(i-j-1)); 表示成b=y+kx的可以求最大值,表示成b=y-kx的可以求最小值。
由于k=Ci是单增的,所以想到斜率优化,可以把原方程化为:dp i=max dpj +[F[j+1]+(j+1)]*Ci - i*Ci 满足(Li+i>=F[j+1]+j+1);
而由于有括号里的限制,我们不能简单的斜率优化DP。 而考虑分治,分治的情况下,我们可以把Mid左边的按照Fi+i排序,右边的按照Li+i排序,如果满足括号条件,则把左边加入凸包, 右边更新答案。 这个时候由于不是按下标插入,所以x不是单调的,所以我们要在凸包上二分答案。
#include<bits/stdc++.h>
#define pii pair<ll,int>
#define mp make_pair
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const int inf=1e9;
ll dp[maxn],F[maxn],C[maxn],L[maxn];
pii a[maxn],b[maxn]; int q[maxn],top;
ll getans(int p,int k)
{
return dp[k]+C[p]*F[k+]-C[p]*p;
}
void update(int p)
{
if(top==) return;int L=,R=top-,Mid;
dp[p]=max(dp[p],getans(p,q[top]));
while(L<=R){
Mid=(L+R)>>;
ll tmp1=getans(p,q[Mid]),tmp2=getans(p,q[Mid+]);
if(tmp1>tmp2) R=Mid-,dp[p]=max(dp[p],tmp1);
else L=Mid+,dp[p]=max(dp[p],tmp2);
}
}
bool check(int p){
return (dp[p]-dp[q[top]])*(F[p+]-F[q[top-]+])<=
(dp[p]-dp[q[top-]])*(F[p+]-F[q[top]+]);
}
void add(int p)
{
if(dp[p]==-inf) return ;
if(top>&&F[p+]==F[q[top]+]&&dp[p]>dp[q[top]]) top--;
while(top>&&check(p)) top--;
q[++top]=p;
}
void solve(int Le,int Ri)
{
if(Le==Ri) return ;
int Mid=(Le+Ri)>>;
solve(Le,Mid);
int tot1=,tot2=; top=;
rep(i,Le,Mid) a[++tot1]=mp(F[i+],i);
rep(i,Mid+,Ri) b[++tot2]=mp(L[i],i);
sort(a+,a+tot1+); sort(b+,b+tot2+);
reverse(a+,a+tot1+); reverse(b+,b+tot2+);
for(int i=,j=;i<=tot2;i++){
while(j<=tot1&&b[i].first<=a[j].first){
add(a[j].second); j++;
}
update(b[i].second);
}
solve(Mid+,Ri);
}
int main()
{
int N; scanf("%d",&N);
rep(i,,N) scanf("%lld",&F[i]),F[i]+=i;
rep(i,,N) scanf("%lld",&C[i]);
rep(i,,N) scanf("%lld",&L[i]),L[i]+=i;
rep(i,,N) dp[i]=-inf;
solve(,N);
if(dp[N]==-inf) puts("Impossible");
else printf("%lld\n",dp[N]);
return ;
}
Gym - 101806R :Recipe(分治+斜率优化)的更多相关文章
- UOJ#7. 【NOI2014】购票 点分治 斜率优化 凸包 二分
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ7.html 题解 这题是Unknown的弱化版. 如果这个问题出在序列上,那么显然可以CDQ分治 + 斜率 ...
- BZOJ3672 [Noi2014]购票 【点分治 + 斜率优化】
题目链接 BZOJ3672 题解 如果暂时不管\(l[i]\)的限制,并假使这是一条链 设\(f[i]\)表示\(i\)节点的最优答案,我们容易得到\(dp\)方程 \[f[i] = min\{f[j ...
- 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp
题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...
- BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化
BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参 ...
- BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化
BZOJ_1492_[NOI2007]货币兑换Cash_CDQ分治+斜率优化 Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券 ...
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...
- [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)
[BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...
- BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]
传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...
- bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5541 Solved: 2228[Submit][Sta ...
随机推荐
- Vue中 computed 和 methods的区别
涉及到计算部分的时候,计算属性是基于它们的依赖进行缓存的,如果说值不变,那么它就不会去重新执行,只有当值发生了改变,它才会去重新执行一次,其它时候它都是缓存的.而方法则会反复计算处理.二者之间的差距就 ...
- Linux只下载不安装软件包
有时我们并不需要安装软件而只要下载软件包. 包格式 命令 命令所属包 命令下载格式 rpm yumdownloader yum-utils yumdownloader package_name deb ...
- kiss prefix paleo,per,pen,pan,para out 1
1● paleo 2● per 3● pen 4● pan 5● para 1★ paleo 古 2★ para ,辅助,在旁边 3★ pan 广泛的 4★ per 假,坏,自始自 ...
- Win系列:VC++编写自定义组件
在Visual Studio 中新建一个Visual C++的 Windows应用商店的Windows运行时组件项目,并将项目命名为FilePickerComponent.然后在项目的解决方案资源管理 ...
- 用linux命令连接无线网络-转载
首先是用到的工具: ifconfigrouteiwlistiwconfig 后两个是无线工具 从现在开始,按我的步骤做 (##后面的是说明部分) 1.开启无线,如果是笔记本,开启无线开关,或用Fn+F ...
- [Codeforces513E2]Subarray Cuts
Problem 给定一个长度为n的数字串,从中选取k个不重叠的子串(可以少选),将每个串求和si 求max|s1 - s2| + |s2 - s3| + ... + |sk - 1 - sk|(n & ...
- (C/C++学习笔记) 二十四. 知识补充
二十四. 知识补充 ● 子类调用父类构造函数 ※ 为什么子类要调用父类的构造函数? 因为子类继承父类,会继承到父类中的数据,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程. ...
- linux centos7 安装mono
1.看官方的命令: 另外一种是下载压缩包解压之后安装: https://apps.fedoraproject.org/packages/mono/ 三.安装Mono需要的GDI+兼容API的库Libg ...
- 记录搭建ssm项目
搞java也快3年了,搭建一个ssm居然有点吃力. 参考链接:https://blog.csdn.net/gebitan505/article/details/44455235/ 环境准备:jdk8. ...
- 异常 No module named 'numpy.core._multiarray_umath
No module named 'numpy.core._multiarray_umath 解决方法: 1. 可能是由于模型保存时出错,导致模型没有保存成功,此时删掉保存的模型即可 2. numpy版 ...