首页 > 其他分享 >题解 洛谷 P2885 [USACO07NOV]Telephone Wire G

题解 洛谷 P2885 [USACO07NOV]Telephone Wire G

时间:2022-12-11 21:25:50浏览次数:71  
标签:Wire 洛谷 minn min int 题解 ll times ge

1. 题面描述

题目链接

给出 \(n\) 棵树的高度。

你可以进行任意次操作,每次操作形如:把某棵树增高 \(x\),代价为 \(x^2\)(注意:不能将一棵树的高度减少)。

在操作完之后,一个状态的代价定义为相邻两树高度差的和 \(\times c\)。

求最小代价。

\(n\le 10^5\),\(a[i],x\le 100\),其中 \(a[i]\) 表示第 \(i\) 棵树的高度。

2. 分析

考虑 DP。

设 \(f[i][j]\) 表示操作完前 \(i\) 棵树,其中第 \(i\) 棵树的高度为 \(j\) 时的最小代价。于是状态转移方程:

\(f[i][j]=min_{k\ge a[i-1]}\{f[i-1][k]+c\times \left|j-k\right|\}+(j-a[i])^2,~~j\ge a[i]\)。

初值 \(f[1][i]=(i-a[1])^2,~~i\ge a[1]\)。

答案 \(ans=min\{f[n][i]\}\)。

时间复杂度 \(O(n\times max(a[i])^2)\)

考虑优化。

先把绝对值拆开。于是状态转移方程:

\(f[i][j]= \begin{cases} min_{k\ge a[i-1]}\{f[i-1][k]+c\times (j-k)\}+(j-a[i])^2,~j\ge k\\ min_{k\ge a[i-1]}\{f[i-1][k]+c\times (k-j)\}+(j-a[i])^2,~j<k\\ \end{cases},~~j\ge a[i]\)

整理,得:

\(f[i][j]= \begin{cases} min_{k\ge a[i-1]}\{f[i-1][k]-c\times k)\}+c\times j+(j-a_i)^2,~j\ge k\\ min_{k\ge a[i-1]}\{f[i-1][k]+c\times k)\}-c\times j+(j-a_i)^2,~j<k\\ \end{cases},~~j\ge a[i]\)

因为两个式子条件不一样,于是考虑分别处理,首先观察第一个式子:

\(f[i][j]=min_{k\ge a[i-1]}\{f[i-1][k]-c\times k)\}+c\times j+(j-a_i)^2,~~j\ge k~\&\&~j\ge a[i]\)

发现 \(k\) 的取值范围随着 \(j\) 的递增而增大,并且左端点固定,于是考虑在转移时使用一个变量来维护合法的 \(k\) 的最大值。

观察第二个式子:

\(f[i][j]=min_{k\ge a[i-1]}\{f[i-1][k]+c\times k)\}-c\times j+(j-a_i)^2,~~j<k~\&\&~j\ge a[i]\)

发现 \(k\) 的取值范围随着 \(j\) 的递减而增大,并且右端点固定为上界,于是考虑使用一个变量来维护合法的 \(k\) 的最大值。

这时时间复杂度就被优化为了 \(O(n\times max(a[i]))\)。

注意转移时循环的上下界,因为上述式子中的 \(j\) 和 \(k\) 都有取值范围的限制。

3. 代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,W=105;
const ll inf=0x3f3f3f3f3f3f3f3f;

int n,c;
int a[N];
ll f[N][W];

inline ll sq(ll x) {return 1ll*x*x;}

int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin>>n>>c;
	for (int i=1; i<=n; i++) cin>>a[i];
	memset(f,0x3f,sizeof f);
	for (int i=a[1]; i<=100; i++) f[1][i]=sq(i-a[1]);
	for (int i=2; i<=n; i++) {
		ll minn=inf;
		for (int j=a[i-1]; j<=100; j++) {
			minn=min(minn,f[i-1][j]-1ll*c*j);
			if (j>=a[i]) f[i][j]=minn+1ll*c*j+sq(j-a[i]);
		}
		minn=inf;
		for (int j=100; j>=a[i]; j--) {
			f[i][j]=min(f[i][j],minn-1ll*c*j+sq(j-a[i]));
			if (j>=a[i-1]) minn=min(minn,f[i-1][j]+1ll*c*j);
		}
	}
	ll ans=inf;
	for (int i=1; i<=100; i++) ans=min(ans,f[n][i]);
	cout<<ans<<'\n';
	return 0;
}

本文完。

标签:Wire,洛谷,minn,min,int,题解,ll,times,ge
From: https://www.cnblogs.com/XeRnHe/p/Solution-Luogu-P2885.html

相关文章

  • 题解 洛谷 P3594 [POI2015] WIL
    1.题面描述题目链接给定一个长度为\(n\)的序列,你有一次机会选中一段连续的长度不超过\(d\)的区间,将里面所有数字全部修改为\(0\)。请找到最长的一段连续区间,使得该......
  • 题解 CodeForces 940E Cashback
    1.题面描述题目链接给定长为\(n\)的序列和一个整数\(c\),你需要将其分为若干段。对于每一段,若其长度为\(k\),则可以删除其中前\(\lfloor\frac{k}{c}\rfloor\)小的......
  • 题解 洛谷 P3793 由乃救爷爷
    1.题面描述题目链接给定长为\(n\)的序列,\(m\)次询问,查询区间最大值。\(n,m\le10^7\),数据随机。2.分析经典的静态区间最小值问题,经典题目配经典算法,考虑到ST表......
  • NOIP2022 题解
    A.种花枚举\((x_2,y_0)\),考虑\(x_1\)可能在哪些位置,显然是在\(x_2\)往上的一个极长连续0段上。考虑如果固定了\(x_1\)的位置后怎么计算C形的数量,我们预处理......
  • CF1182E 题解
    前言题目传送门!更好的阅读体验?\(\text{zltqwq}\)推荐矩阵快速幂题目。思路......
  • P4902 乘积 题解
    乘积给出\(A\),\(B\),求下面的式子的值.\[\prod_{i=A}^{B}\prod_{j=1}^{i}(\frac{i}{j})^{\left\lfloor\frac{i}{j}\right\rfloor}\(\bmod\19260817)\]包含\(T\)组......
  • 【题解】CF1764C Doremy's City Construction
    题目传送门思路首先我们思考一个性质,由于不能有连续单调不升/不降的三个点连在一起,所以对于单个点来讲,显然要么只和比它大的连边(称为A类点),要么只和比它小的连边(称为B类点......
  • SP8547 题解
    SP8547题解题意简述:给定\(n\),找到能够使得辗转相除法执行\(n\)次的两个数,使得这两个数的和最小,输出这两个数。\(n\le10^{18}\)分析:对于这种题,一看就是猜结论的题,因......
  • [NOIP2022] 喵了个喵 题解
    [NOIP2022]喵了个喵题解先考虑\(k=2n-2\),这个数字提示我们每个栈放两种颜色,剩下一个栈辅助操作。那么颜色被分为两类在栈底,可以通过操作2消去。在栈顶,可以通过操作1......
  • VUE3 API之reactive和ref常见问题解决
    reactive解构最深的一层,失去响应性问题<scriptsetuplang="ts">lettarget={a:{b:1}};lettarget1={c:1};constobj=reactive(target)constobj1=......