hdu 3507 Print Article

本文深入探讨了斜率dp算法的原理及其在解决特定类型动态规划问题时的应用。通过实例展示了如何优化求解过程,提高算法效率。

斜率dp简单题

#include <STDIO.H>
#include <STRING.H>
/*
	dp[i] = min( dp[j] + M + (...)^2 )
*/
const int MAXN = 500005;
int n, m;
int da[MAXN], sum[MAXN], dp[MAXN];
int q[MAXN], head, tail;
int getDP(int i, int j)
{
	return dp[j] + m + (sum[i]-sum[j])*(sum[i]-sum[j]);
}
int getUP(int k, int j)
{
	return dp[j]-dp[k] + sum[j]*sum[j] - sum[k]*sum[k];
}
int getDOWN(int k, int j)
{
	return 2*(sum[j]-sum[k]);
}
int main()   
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
	while (scanf("%d%d", &n, &m) == 2)
	{
		int i;
		for (i = 1; i<= n; i++)
			scanf("%d", &da[i]);
		for (i = 1; i<= n; ++i)
			sum[i] = sum[i-1]+da[i];
		head = tail = 0;
		q[tail++] = 0;
		for (i = 1; i<= n; i++)
		{
			while (tail-head>1 && getUP(q[head],q[head+1])<=sum[i]*getDOWN(q[head],q[head+1]))
				head++;
			dp[i] = getDP(i, q[head]);
			while (tail-head>1 && getUP(q[tail-2],q[tail-1])*getDOWN(q[tail-1],i)
				>=getUP(q[tail-1],i)*getDOWN(q[tail-2],q[tail-1]))
				tail--;
			q[tail++] = i;
		}
		printf("%d\n", dp[n]);
	}
	return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值