业余acmer笔记·斜率优化DP

概念

和平行四边形优化一样,往往起到对DP降维的作用。
使用条件是满足决策单调性。
关于决策单调性的定义
在这里插入图片描述
截图来自参考博客

四边形不等式的运用参考博客

斜率DP的详细讲解参考博客

补一个凸包的板子参考博客

另外,四边形不等式只是验证决策单调性,而决定取上还是下凸包则由斜率不等式的推导决定。

一道与主题不相关的例题

原题地址
在这里插入图片描述
代码:
目前找到了两种解法
代码来源
在这里插入图片描述
这个解法有传统dp的意味,即得到dp[i]有两种方法,一种是重新划出一个长度为k的序列,另一种是将第i个元素并入上一个序列中。

但学习了斜率优化dp后,更推崇命题人给的解法
代码来源
在这里插入图片描述
在这里插入图片描述
这有斜率dp的一个思想: 决策点(即j点)与目标点(即i点),在状态转移方程中将含有i的点和含有j的点分离。
当不能分离的时候,就可以考虑斜率dp了。

Necklace

原题地址
在这里插入图片描述
在这里插入图片描述
代码
题目大意:将一个有k个元素的环分成k个部分,每个部分的权值是其元素和的平方,问权值总和最小值。
四边形不等式:
在这里插入图片描述
淘汰条件见参考博客
显然是一个下凸包优化
在这里插入图片描述
乱写的推导过程

#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 202
#define INF 0x3f3f3f3f
#define Re register ll
int T, n, k, tl = 0, h = 0, Q[maxn];
ll dp[maxn][maxn], a[maxn], sum[maxn], b[maxn];
//inline int get(int j) { return (j - 1) % n + 1; }
inline ll X(Re j) { return sum[j]; }
inline ll Y(Re j, Re v) { return dp[j][v] + sum[j] * sum[j]; }
inline long double slope(Re i, Re j, Re v) { return (long double)(Y(j, v - 1) - Y(i, v - 1)) / (X(j) - X(i)); }
int main()
{
	ios::sync_with_stdio(false);
	int i, j, r, p;
	cin >> T;
	while (T--)
	{
		ll ans = INF;
		tl = h = 0;
		Q[++tl] = 0;
		cin >> n >> k;
		for (i = 1; i <= n; i++)cin >> a[i];
		for (i = 1; i <= n; i++)
		{
			for (j = 1; j <= n; j++)
			{
				b[j] = a[((j + i - 1) > n ? (j + i - 1 - n) : (j + i - 1))];
			}
			for (j = 1; j <= n; j++) sum[j] = sum[j - 1] + b[j];
			for (j = 1; j <= n; j++) dp[j][1] = sum[j] * sum[j];
			for (p = 2; p <= k; p++)
			{
				tl = h = 0;
				Q[++tl] = p - 1;
				for (j = p; j <= n; j++)
				{
					while (h < tl && slope(Q[h], Q[h + 1], p) <= 2 * sum[j]) ++h;
					dp[j][p] = dp[r = Q[h]][p - 1] + (sum[r] - sum[j])*(sum[r] - sum[j]);
					while (h < tl && slope(Q[tl - 1], Q[tl], p) >= slope(Q[tl - 1], j, p)) --tl;
					Q[++tl] = j;
				}
			}
			ans = min(ans, dp[n][k]);
		}
		cout << ans << endl;
	}
	return 0;
}

神奇的是代码一直TLE,感觉和参考博客的差不多,唯一合理的解释就是调用了函数???

另一道偏题的题目

原题地址

荡开一笔,不细讲。这道题展示了传统dp的思维方式,作为对比放在这里。
详细讲解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值