【BZOJ3156】—防御准备(斜率优化)

本文通过斜率优化技术解决了一道动态规划问题。利用自定义结构体表示点,并实现点运算,通过比较斜率的方式进行优化。代码中详细展示了如何进行斜率优化,包括查找最优前缀状态和维护凸包等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门


水题
随便推个式子斜率优化就完了

#include<bits/stdc++.h>
using namespace std;
const int N=1000005;
#define int long long
#define gc getchar
inline int read(){
	char ch=gc();
	int res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
#define ll long long
#define cs const
#define pb push_back
#define db double
struct pt{
	db x,y;
	pt(db _x=0,db _y=0):x(_x),y(_y){}
	friend inline pt operator +(cs pt &a,cs pt &b){
		return pt(a.x+b.x,a.y+b.y);
	}
	friend inline pt operator -(cs pt &a,cs pt &b){
		return pt(a.x-b.x,a.y-b.y);
	}
	friend inline db operator *(cs pt &a,cs pt &b){
		return a.x*b.y-a.y*b.x;
	}
	inline double slope(){
		return y/x;
	}
}p[N];
int stk[N],top;
ll f[N];
int a[N],n;
inline void trans(int i,int j){
	f[i]=f[j]+1ll*(i-j)*(i-j-1)/2+a[i];
}
inline bool check(int k,double s){
	return (p[stk[k]]-p[stk[k-1]]).slope()<2*s;
}
signed main(){
	freopen("lx.cpp","r",stdin);
	n=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=n;i++){
		int l=1,r=top,res=0;
		while(l<=r){
			int mid=(l+r)>>1;
			if(check(mid,i))l=mid+1,res=mid;
			else r=mid-1;
		}
		trans(i,stk[res]);
		p[i].x=i,p[i].y=2ll*f[i]+1ll*i*i+i;
		while(top&&(p[stk[top]]-p[stk[top-1]])*(p[i]-p[stk[top-1]])<=0)top--;
		stk[++top]=i;
	}
	cout<<f[n];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值