首页 > 其他分享 >P3195

P3195

时间:2024-02-19 22:00:30浏览次数:32  
标签:Slope le 2s int sum P3195 ll

P3195

  • 斜率优化

  • 暴力转移:

    • \(f(i)\) 表示考虑到第 \(i\) 个玩具达成的最小费用
    • \(f(i) = min(f(j) + (i - j + \sum_{j + 1}^{i} c - L) ^ 2)\)
    • 设 \(s_i = \sum_1^i + i\)
    • \(f(i) = min(f(j) + (s_i - s_j - 1 - L) ^ 2)\)
    • 不妨设 \(L = L + 1\)
    • \(f(i) = min(f(j) + (s_i - s_j - L) ^ 2)\)​
  • 消掉常数项 \(f(j) + (s_j + L) ^ 2 - 2s_is_j\)

    • 设 \(g(i) = f(i) + (s_i + L) ^ 2\)
  • 设 \(j < k < i\) 且 \(f(j) \ge f(k)\)

    • 则 $g(k) -2s_is_k \le g(j) - 2s_is_j $
    • \(\frac{g(k) - g(j)}{s_k - s_j} \le -2s_i\)​
  • 设点 \(A, B, C = (s_i, f(i) + (s_i + L) ^ 2)\)

    • 设 $2s_i = s_0 $ 斜率为 \(k_1, k_2\)
    • 若 \(s_0 \le k_1 \le k_2\) 则 A > B > C
    • 若 \(k_2 \le s_0 \le k_1\) 则 A, C > B
    • 若 \(k_2 \le k_1 \le s_0\)​则 C > B > A
  • 跟 B 始终无关 -> A, C 连边构成下凸包

  • 关于代码

    • Slope(q[l + 1], q[l]) <= 2.0 * sum[i] 说明 q[l + 1] > q[l], 舍弃 q[l]
    • Slope(q[r], q[r - 1]) >= Slope(i, q[r]) 说明 i > q[r] > q[r - 1],舍弃 q[r - 1]
# include <bits/stdc++.h>
# define int long long
# define double long double
using namespace std;
const int MOD = (int)1e9 + 7;
const int N = (int)1e6 + 10;

int n, ll;
int c[N], sum[N];
int q[N], l, r;
int dp[N];

int X(int x){
	return sum[x];	//
}

int Y(int x){
	return dp[x] + (sum[x] + ll) * (sum[x] + ll);
}

double Slope(int x, int y){
	return 1.0 * (Y(x) - Y(y)) / (X(x) - X(y));
}

signed main(){
//	freopen("1.in", "r", stdin);
	cin >> n >> ll;
	for(int i = 1; i <= n; i++){
		cin >> c[i];
		sum[i] = sum[i - 1] + (c[i] + 1);
	}
	ll++;	// ll 和 1 合并, 见式子 
	
	l = 1, r = 1;
	q[1] = 0;
	for(int i = 1; i <= n; i++){
		while(l < r && Slope(q[l + 1], q[l]) <= 2.0 * sum[i]){
			l++;
		}
		int j = q[l];
		dp[i] = dp[j] + (sum[i] - sum[j] - ll) * (sum[i] - sum[j] - ll);
		while(l < r && Slope(q[r], q[r - 1]) >= Slope(i, q[r])) {
			r--;
		}
		q[++r] = i;
	}
	cout << dp[n] << "\n";
}

注:a > b 表示 a 比 b 优

标签:Slope,le,2s,int,sum,P3195,ll
From: https://www.cnblogs.com/wangyangjena/p/18022049

相关文章

  • P3195 [HNOI2008]玩具装箱 题解
    首先先写dp方程非常简单\(\mathit{f}_{i}=\min(\mathit{f}_{j}+(\mathit{c}_{i}+i-j-1-L-\mathit{c}_{j})^2)\)(其中\(\mathit{c}_{i}\)表示长度前缀和)然后发现括号......
  • P3195 [HNOI2008]玩具装箱
    题目:P3195[HNOI2008]玩具装箱 一道斜率优化dp题。先考虑状态和转移方程:令$dp[i]$表示装前$i$个玩具所需要最小花费,$j$表示上一个容器右端点,$sum[i]$表示前$i$个玩具长......
  • 洛谷P3195 玩具装箱 题解报告
    题目地址题意:如题所述。分析:斜率优化dp模板题。题目没看清就下手,自以为题面所述中i>j;原始dp式子也没设计准确。中途在错误方向上头铁时,甚至没注意到横坐标是沿......
  • P3195 [HNOI2008]玩具装箱
    给定序列\(C\),将原序列拆成几个部分,每个部分\([i,j]\)费用为\(j-i+\sum^{j}_{k=i}C_k\),最小化费用。\(n\leq5\times10^4\)。定义\(sum[i]\)为前\(i\)项的......