HDU 3507 Print Article

本文深入解析斜率优化动态规划技巧,通过实例演示如何利用斜率优化降低复杂度,适用于处理特定类型的DP问题,如最小费用求解。文章提供代码实现,帮助读者理解斜率优化在实际问题中的应用。

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

这是一道斜率优化简单题,但是他不给清楚数据范围。注意: 0 ≤ C i 。 0\le C_i。 0Ci
不会斜率优化,请戳这里。
f [ i ] 表 示 对 前 i 个 单 词 进 行 处 理 的 最 低 费 用 , s 为 c 的 前 缀 和 f[i]表示对前i个单词进行处理的最低费用,s为c的前缀和 f[i]i,sc
则有: f [ i ] = m i n     f [ j ] + ( s [ i ] − s [ j ] ) 2 + m    ( 0 ≤ j &lt; i ) f[i]=min ~~~f[j]+(s[i]-s[j])^2+m ~~ (0\le j&lt;i) f[i]=min   f[j]+(s[i]s[j])2+m  (0j<i)
化成 y = k x + b : y=kx+b: y=kx+b:
f [ j ] + s [ j ] 2 = 2 s [ i ] ∗ s [ j ] + f [ i ] − s [ i ] 2 + m f[j]+s[j]^2=2s[i]*s[j]+f[i]-s[i]^2+m f[j]+s[j]2=2s[i]s[j]+f[i]s[i]2+m
k , x 满 足 单 调 递 增 , 即 可 用 斜 率 优 化 做 。 k,x满足单调递增,即可用斜率优化做。 k,x
代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int n,m,q[N],l,r;
ll f[N],s[N];
double y(int i){return (double)f[i]+s[i]*s[i];}
double x(int i){return (double)s[i];}
double slope(int i,int j)
{
	return (y(i)-y(j))/(x(i)-x(j));
}
#define g getchar()
template<class o>//快读 
void qr(o&x)
{
	char c=g;bool v=x=0;
	while(!( ('0'<=c&&c<='9') || c=='-' ))c=g;
	if(c=='-')v=1,c=g;
	while('0'<=c&&c<='9')x=x*10+c-'0',c=g;
	if(v)x=-x;
}
#undef g
int main()
{
	while(~scanf("%d",&n))
	{
		qr(m);
		for(int i=1;i<=n;i++)
		{
			qr(s[i]);
			if(!s[i]){i--,n--;continue;}//坑点。
			s[i]=s[i]+s[i-1];
		}
		l=r=1;q[1]=0;
		#define j q[l]
		for(int i=1;i<=n;i++)
		{
			while(l<r&&slope(q[l],q[l+1])<=(double)(s[i]<<1))l++;
			f[i]=f[j]+(s[i]-s[j])*(s[i]-s[j])+m;
			while(l<r&&slope(q[r-1],q[r])>=slope(q[r],i))r--;
			q[++r]=i;
		}
		#undef j
		printf("%lld\n",f[n]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Infinite_Jerry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值