10.18

10.18

选人
吉吉国王现在想选出组人来组成部队,现在他有个人可以选择,每个
人都有一个战力值。但是吉吉国王非常笨,因此他只能选择连续的一
段区间中的人来组成一个部队,所以选出的这组人在这到个人中没有
重合的部分。吉吉国王希望这组人的战斗力之和最大,你需要告诉吉
吉国王最大的战斗力之和是多少。
1<=n<=1e5,1<=m<=100,-1e9<=a\(_{i}\)<=1e9
考虑dp:
设f\(_{i,j}\) = 前i个人划分成j组的最大战斗力之和
可以枚举上一组的开头k
则有状态转移方程:
f\(_{i,j}\) = max{f\(_{k-1,j-1}\)+S\(_{i}\)-S\(_{k-1}\)}
考虑优化
不妨多加一维描述i选或不选
若不选i,则直接继承状态f\(_{i,j,0}\)=max{f\(_{i-1,j,1/0}\)}
如果选i,考虑三种情况:
1)与i-1并成一组
2)在不选i-1的情况下以i为开头新开一组
3)在选i-1的情况下以i为开头新开一组
则有状态转移方程:
f\(_{i,j,1}\)=max{f\(_{i-1,j,1}\)+a\(_{i}\) , f\(_{i-1,j-1,0}\)+a\(_{i}\) , f\(_{i-1,j-1,1}\)+a\(_{i}\)}
时间复杂度O(nm)


涂色
给定一排长度为的瓷砖,每块瓷砖都有一个数字。现在需要对这些瓷
砖进行涂色,每次涂色都可以选一段之前没有涂过的区间,涂色的代
价就是这段区间种不同的数字的个数的平方,比如对于,选择对区间
涂色,因为到有三种数字,那么代价就是。现在需要求出把所有瓷砖
都涂上颜色的最小代价
1<=n<=5e4,1<=a\(_{i}\)<=1e9
考虑dp:
设f\(_{i}\)=从1涂到i的最小代价
朴素dp枚举上一次涂色的终点j,遍历j到i进行转移,时间复杂度O(n\(^{3}\))
注意到如果一个一个进行涂色,则代价为n,所以我们dp得出的答案都必须小于等于n
即我们dp每次涂色区间中不同数的个数不能超过sqrt(n)

但如果我们暴力循环加上判断限制也会超时
注意到如果当前枚举到i,则1~i-1中与i同色的位置都会失效,所以我们不妨使用链表进行优化,每次转移时将所有与i同色的位置跳过,可以实现O(nsqrt(n))


序列
给定整数 n 和长度为 n 的序列 a。
从位置 i 跳到位置 j(1≤i≤j≤n) 需要花费min(a\(_{i}\),a\(_{i+1}\),...,a\(_{j}\)) * (j-i)\(^{2}\)
对于 k=1,2,⋯,n,求出从位置 1 经若干次跳跃后跳到位置 k 需要的最小金币总数。
考虑dp:
设f\(_{i}\) = 从1跳到i需要的最小金币数
朴素dp:枚举终点i与起点j,预处理i~j的min,时间复杂度O(n\(^{2}\))
我们可以注意到两个性质:
1)若直接从i一步跳到j,那么代价一定不会比i->k->j更优(k为[i,j]的区间最小下标)
证:我们知道一步从i跳到j的代价为a\(_{k}\) * (j-i)\(^{2}\)
而i->k->j的代价为a\(_{k}\) * ((k-i)\(^{2}\)+(j-k)\(^{2}\))
令x=k-i,y=j-k
则i->j的代价为a\(_{k}\)*(x+y)\(^{2}\)
i->k->j的代价为a\(_{k}\)*(x\(^{2}\)+y\(^{2}\))
易知(x+y)\(^{2}\)>x\(^{2}\)+y\(^{2}\)
所以i->k->j必定不劣于i->j
2)对于一个最小值a\(_{i}\) , 一定满足它前一次与后一次的步长不超过n/a\(_{i}\)
证:
对于一个步长d,如果每次只跳1的距离,那么每次的花费都不超过n,总花费不超n*d
然而一步跳的花费为a\(_{i}\) * d\(^{2}\)
要满足一步跳更优,就有a\(_{i}\) * d\(^{2}\)≤n * d ,既d≤n/a\(_{i}\)

有了以上性质,物品们只要对于每个i,考虑以a\(_{i}\)为最小值转移即可,可以证明时间复杂度为O(nsqrt(n))
(i)对于a\(_{i}\)≥sqrt(n),步长上限d=n/a\(_{i}\)≤sqrt(n),所以时间复杂度不超O(nsqrt(n))
(ii)对于a\(_{i}\)<sqrt(n),将相同的a\(_{i}\)放在一起考虑。
对于一个a\(_{i}\),以他们为最小值的区间长度之和为O(n),最多有sqrt(n)种数,所以时间复杂度不超O(nsqrt(n))


数组
你得到了一个长度为n的数组a和一个整数c
这个数组非常神奇,划分后对于任意长度为k的数组,它的值为数组中除最小的[k/c]个元素外其他元素的和。
求将数组划分为若干个连续的子数组后,所有子数组值的和的最小值。
考虑dp:
因为直接求最小值很难求,我们不妨将目标转变为求减去的最大值
设f\(_{i}\)为前i个数能被减去的最大值之和
我们贪心的想如何划分数组才能使减去的值最大
假设我们有区间[L,R],区间长度为len=R-L+1
1)len<c,则此区间无法提供贡献
2)c<=len<2c,此时此区间能提供一个减去的数,记为[L,R]\(_{min}\)
我们考虑将区间[L,R]划分为两个区间
[L,L+c-1] , [L+c,R]。
此时区间[L,L+c-1]能提供一个贡献,记为[L,L+c-1]\(_{min}\)
我们可以发现,[L,L+c-1]\(_{min}\)不小于[L,R]\(_{min}\),即将[L,R]划分为[L,L+c-1]与[L+c,R]的贡献不劣于[L,R]的贡献
我们不妨将情况扩大
3)kc <= len < (k+1)c**
此时区间[L,R]能提供k个贡献,记为d\(_{1...k}\),此时我们将区间[L,R]划分为k+1个区间,分别为[L,L+c-1],[L+c,L+2c-1],...,[L+kc,R]
此时我们发现,k个有效区间能提供的贡献必定不劣于[L,R]提供的贡献,于是有贪心思想:
我们将每个区间划分为若干个长度为c的区间与若干个长度为1的区间,这种划分方法不劣于其他任意一种划分方法。
推的状态转移方程:
f\(_{i}\) = max{f\(_{i-1}\),f\(_{i-c}\)+[i-c+1,i]\(_{min}\)}
其中,[i-c+1,i]\(_{min}\)我们可以使用**单调队列维护,时间复杂度O(n)

posted on 2025-10-19 21:17  Jklans  阅读(7)  评论(0)    收藏  举报