题目描述
小 B 喜欢玩游戏。
有一天,小 B 在玩一个序列上的游戏,他得到了正整数序列{ai}以及一个常数c 。
游戏规则是,玩家可以对于每一个ai 分别加上一个非负整数x ,代价为 x2,完成所有操作之后,需要额外花费的代价就是所有相邻位置上数之差的绝对值总和再乘上c 。
小 B 觉得这个游戏很简单,想以最小的代价通过关卡,请你来帮助他求出总代价的最小值。
输入格式
第一行两个整数n,c
第二行 n个整数表示{ai}
输出格式
一行一个整数表示最小代价。
 
 

花了我一天多的时间......

先放代码:(注释应该比较详细了)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,T=18;
int n,c,a[N],lg[N],ans;
#define fi first
#define se second
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
pair<int,int> st[N][T];
pair<int,int> get(int l,int r){
int p=lg[r-l+1];
return max(st[l][p],st[r-(1<<p)+1][p]);
}
struct node{
int x,h;//x是往上抬的步数总和、h是抬高到的高度
}; void ST(){//ST表求区间max
lg[1]=0;
for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int j=1;j<=T-1;j++)
for(int i=1;i+(1<<j-1)<=n;i++)
st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
} node solve(int l,int r,int k){
if(l>r) return (node){0,-1};
int id=get(l,r).se;
node L=solve(l,id-1,a[id]),R=solve(id+1,r,a[id]);
if(L.h!=-1&&L.h!=a[id]||R.h!=-1&&R.h!=a[id]) return (node){0,0};
//一边没有提上来,之后不需要提了(大佬:直接溜了)
int len=r-l+1,x=L.x+R.x,op=0,ll=0,rr=1e7;
if(l==1||r==n) op=1;//边界
else op=2;
while(ll<=rr){
int mid=(ll+rr)>>1;
if(2*x+len+2*len*mid>op*c) rr=mid-1;
else ll=mid+1;
}//二分寻找应该向上抬多少层
if(ll<1) return (node){x,a[id]};//抬不了
ll=min(ll,k-a[id]);//抬的高度不能超过k
ans+=(2*x+len+2*(x+(ll-1)*len)+len)*ll/2-op*c*ll;//等差数列求和
return (node){x+ll*len,a[id]+ll};
} signed main(){
n=read();c=read();
for(int i=1;i<=n;i++){
a[i]=read();
st[i][0]=make_pair(a[i],i);
ans+=c*(i!=1)*abs(a[i]-a[i-1]);//初始代价
}
ST();int k=get(1,n).fi;
solve(1,n,k);
cout<<ans<<endl;
return 0;
}
/*
4 3
2 1 2 3
*/

原数列将数值看做高度,相当于是一个连绵起伏,蜿蜒曲折的山脉(文笔真好),我们要找到波谷,对其尝试往上抬,抬的具体数值用二分来寻找。

大佬的草稿,用于解释solve()的步骤:(仰望大佬)

最新文章

  1. 【JavaScript】javascript中伪协议(javascript:)使用探讨
  2. c#.net网页跳转七种方法
  3. setTimeout 学习闭包
  4. python(25)下载文件
  5. Bootstrap学习笔记1
  6. [LeetCode]题解(python):052-N-Queens II
  7. 进程间通信之管道(pipe、fifo)
  8. hdu 4715 Difference Between Primes(素数筛选+树状数组哈希剪枝)
  9. WinCE NAND flash - FAL
  10. 关于smali插桩
  11. window环境变量
  12. 对js运算符“||”和“&amp;&amp;”的总结
  13. 简单的3d变换
  14. 马昕璐201771010118《面向对象程序设计(java)》第七周学习总结
  15. LINUX UBUNTU 快捷键
  16. 【雅思】【写作】【大作文】Report
  17. django项目----函数和方法的区别
  18. python Udp与Tcp
  19. SpringBoot+Mybatis+Generator 逆向工程使用(二)
  20. 技能树升级——Chrome Headless模式 - 全栈客栈 - SegmentFault

热门文章

  1. GCD Compression
  2. 2022-7-20 第七组 pan小堂 String
  3. 15分钟搭建RocketMQ源码调试环境
  4. docker for windows无法共享硬盘
  5. 最佳实践 | 联通数科基于 DolphinScheduler 的二次开发
  6. Dolphin Scheduler 1.2.0 部署参数分析
  7. k8s驱逐篇(2)-kubelet节点压力驱逐
  8. 一文理解Hadoop分布式存储和计算框架入门基础
  9. 演示RabbitMQ的交换类型
  10. TCP/UDP报文格式