斜率优化--P3195 [HNOI2008]玩具装箱

斜率优化的基本形式

对于这样形式的\(dp\)方程:\(dp_i=Min/Max(a_i\times b_j+c_j+d_i)\),其中\(b\)严格单调递增。

该方程的关键点在于\(a_i\times b_j\)这一项,它既有\(i\)又有\(j\),于是单调队列优化不再适用,可以尝试使用斜率优化。

代数理解

因为感觉图像理解并不是很严谨,所以推一下式子,比如这道题 P3195 [HNOI2008]玩具装箱:

转移方程:\(f_i = min(f_j+{(sum_i-sum_j+i-j-1-L)}^2)\) 既然是讲斜率优化,状态转移应该就不用说了把

我们把这一系列的变量分类,把与\(i\)有关和与\(j\)有关的变量分开,\(A = sum_i+i\)\(B = sum_j+j+L+1\)

那么原式子就转化为\(f_i = f_j+{(A-B)}^2 = f_j+A^2+B^2-2AB\) (因为每一个\(i\)只会由一个最优的\(j\)转移过来,所以我们可以先把\(min\)拿掉)

对于两个\(j\)\(1\leq j_1 < j_2\leq n\),如果\(f_{j_2}\)\(f_{j_1}\)更优,那么:

\(f_{j_1}+A^2+{B_1}^2-2AB_1 > f_{j_2}+A^2+{B_2}^2-2AB_2\),变形后可得:\(\frac{(f_{j_2} + {B_2}^2) - (f_{j_1}+{B_1}^2)}{B_2-B_1} < 2A_i\)

可以发现他们两两形式相同,那么我们就可以改写成\(\frac{Y_2-Y_1}{X_2-X_1} < k\)

我们发现当\(j_1\)\(j_2\)连成的直线斜率小于\(k\),选后面的点\(j_2\)更优,那么对答案产生贡献的就是第一个斜率大于\(k\)的前面的点(这好像只能画图理解了,我并不会说明呀)

变形状态转移的方法

\(dp_i=Min/Max(a_i\times b_j+c_j+d_i)\),其中\(i\times j\)的一项里,含\(i\)的是斜率,含\(j\)的是\(x\),剩下右边含\(j\)的是\(y\),其余的是\(b\)

code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int read(){
	int x = 1,a = 0;char ch = getchar();
	while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
	while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
	return x*a;
}
const int maxn = 5e4+10;
int n,l;
double sum[maxn],A[maxn],B[maxn],c[maxn];
double dp[maxn],q[maxn];
double X(int x){return B[x];}
double Y(int x){return dp[x]+B[x]*B[x];}
double solve(int a,int b){return (Y(a)-Y(b))/(X(a)-X(b));}
int main(){
	n = read(),l = read();
	for (int i = 1;i <= n;i++) scanf("%lf",&c[i]),sum[i] = sum[i-1] + c[i];
	for (int i = 1;i <= n;i++) A[i] = sum[i]+i,B[i] = sum[i]+i+l+1;
	B[0] = l+1;
	int head = 1,tail = 1;
	for (int i = 1;i <= n;i++){
		while (head < tail&&solve(q[head],q[head+1]) < 2*A[i]) head++;
		int j = q[head];dp[i] = dp[j]+(A[i]-B[j])*(A[i]-B[j]);
		while(head < tail&&solve(i,q[tail-1]) < solve(q[tail-1],q[tail])) tail--;
		q[++tail]=i;
	}
	printf("%lld\n",(long long)dp[n]);
	return 0;
}
posted @ 2020-11-18 12:18  小又又yyyy  阅读(94)  评论(0编辑  收藏  举报