2021暑期训练dp优化题解

2021 暑假训练 dp 优化题解

AC Codes

A – GTY’s birthday gift

  • 矩阵优化 dp

给出序列 a ,每次从序列选两个数相加后,将新数加入序列 a 问操作 k 次后序列的和最大为多少

序列和最大,每次选当前最大和次大相加, dp[i]=d[i1]+dp[i2] ,由于 k 范围大,无法直接模拟。考虑到操作方式类似斐波那契数列求合,使用矩阵快速幂优化 dp 。注意模数和多组输入。

B – The Battle of Chibi

  • 树状数组优化 dp

给出长度为 n 的序列,问这个序列中有多少个长度为 m 的单调递增子序列

dp[i][j] ,表示到第 i 个数字,长度为 j 的单调递增子序列的个数。

dp[i][j]=k<i,a[k]<a[i]dp[k][j1]

如果单纯枚举转移,不可行。考虑到转移条件的限制,可以将 a[i] 离散化后,使用树状数组计算所以满足条件的状态和。

C – base 基站选址

  • 线段树优化 dp

给出 n 个村庄的横坐标 Di 。要求在这 n 个村庄内最多选择 m 个作为通讯基站,在村庄 i 建造通讯基站的代价为 Ci 。对于村庄 i ,如果其左右距离超过 Si 都没有通讯基站,那么需要额外的 Wi 的代价。求最小代价。

dp[i][j] ,表示在第 i 个村庄,修建第 j 个基站的最小费用。costk,i 表示第 k i 个村庄之间没有被基站 k,i 覆盖的村庄所需的额外费用。

dp[i][j]=mink<idp[k][j1]+costk,i+c[i]

首先考虑如何求出 costk,i 。对于第 i 个村庄,可以二分处理出它所能被覆盖的左右边界为 li , ri 。从 i 推到 i+1 时,对于所有 rk=i 的村庄若从村庄 1lk1 转移过来则必定要赔偿村庄 k 的费用,然后可以用线段树维护区间最小值,从而找到转移位置。

D – Fence

  • 单调队列优化 dp

给出 n 个木块, k 个人。每个人有三个参数 l,p,s , 分别表示每个人最多加工的木块数,每个人加工一个木块的贡献,每个人加工木块区间必须包含的木块编号,求最大贡献和。

dp[i][j] ,表示第 i 个人加工到 j 号木块的最大贡献。

dp[i][j]=max(dp[i1][j],dp[i][j1])dp[i][j]=maxk<i,k<s[i],jkl[i]dp[i1][k]+p[i]×(jk)

然后我们发现转移是选 dp[i1][k]+p[i]×(jk) 最大的进行转移,然后我们可以维护一个递减的单调队列,放当前的值,和位置下标。转移的时候弹出不合法的元素,然后直接取队首进行转移即可。

E – Watching Fireworks is Fun

  • 单调队列优化 dp

主要街道有 n 个区域,从左到右编号为 1 n , 每个相邻部分之间的距离为 1 。在节日期间,将推出烟花爆竹。第 i 次发射是在 ai 部分,发射时间为 ti 。如果你在第 i 次发射时在 x 处,将获得幸福值 bi|aix| 。在单位时间间隔内移动最多 d 个单位,但禁止走出主要街道。此外,可以在初始时刻(时间等于 1)处于任意区域,并希望最大化从观看烟花中获得的幸福总和。

dp[i][j] 表示到放第 i 个烟花的时候站在 j 位置可以获得的最大幸福总和。

dp[i][j]=maxjd×tk,kj+d×tdp[i1][k]+b[i]|a[i]j|

首先烟花要先按照燃放时间排序,对于 dp[i][j]k 的取值范围的长度是固定的,所以可以考虑使用单调队列来维护上一状态的取值,保证转移时取到最大值。

F – Water Balance

  • 单调栈优化 dp

给你 n 个数的序列 a 。每次操作选择一个区间 [l,r] ,把这个区间的数都改为这个区间的平均数。你可以进行任意次操作,使得这个序列的字典序最小。

为使序列的字典序最小,序列中的数一定单调递增。进行区间选择合并时,一定会使之前的区间平均值下降。所以可以使用单调栈来维护区间的合并,合并后区间的权值为平均值。

G – 股票交易

  • 单调队列优化 dp

dp[i][j] 表示第 i 天拥有 j 张股票可以赚到的最多钱数。考虑到两次交易直接需要间隔 w 天,所以 dp[i][j] 可以从 dp[iw1][k] 转移得到。同时还有考虑从前一天直接转移的状态。

dp[i][j]=max(dp[i][j],dp[i1][j])dp[i][j]=maxkas[i]dp[iw1][jk]k×ap[i]dp[i][j]=maxkbs[i]dp[iw1][j+k]+k×bp[i]

由于转移区间有明显的上下边界,可以考虑用单调队列来维护区间最值。

H – 瑰丽华尔兹

  • 单调队列优化 dp

dp[i][j] 表示在每次移动后落在 [i,j] 位置的最大答案。每次移动答案只会从一个方向上转移,同时转移的长度有限制。转移过程和上一题类似,主要是需要考虑四个方向的转移,同时在遇到无法通过的点时需要清空队列。

I – 玩具装箱 toy

  • 斜率优化 dp

dp[i] 表示前 i 件玩具的最小费用, sum[i] 表示前 i 件玩具的前缀和。首先考虑一般转移方程。

dp[i]=min(dp[j]+(sum[i]+isum[j]jL1)2)

如果直接进行转移时间复杂度为 O(n2) ,肯定无法解决。

a[i]=sum[i]+ib[i]=sum[i]+i+L+1

dp[i]=dp[j]+(a[i]b[j])2

展开后:

dp[i]=dp[j]+a[i]22×a[i]×b[j]+b[j]2

移项可得:

2×a[i]×b[j]+dp[i]a[i]2=dp[j]+b[j]2

b[j] 看作 xdp[j]+b[j]2 看作 y 可得:

2×a[i]×x+dp[i]a[i]2=y

这个式子就可以看作一条斜率为 2a[i] 的直线,由于 a[i] 为固定值。

对于 i 的两个可转移状态 j1,j2 ,如果 j2j1 优,可得:

y[j1]2a[i]x[j1]y[j2]2a[i]x[j2]2a[i]y[j2]y[j1]x[j2]x[j1]

所以对于当前的后续状况,只需要考虑斜率,保证斜率最优的情况,就能确保答案最优。

同样可以使用单调队列来保存候选状态。

J – 征途

  • 斜率优化 dp

x[i] 表示第 i 天走的路程, x0x[i] 的平均值。

s2=(x[i]x0)2ms2=x[i]2+x202x[i]x0ms2=x[i]2mx20m2s2=mx[i]2m2x20

由于 x0 是一个定值,题目本质就转换为求 x[i]2 的最小值。

状态转移公式和上一题类似,只不过多了分段此时的限制,所以状态转移需要做 m 次。

K – 仓库建设

  • 斜率优化 dp

dp[i] 表示在 i 位置建设了仓库的最小代价。

sump[i]=jip[i]sum[i]=jip[i]×x[i]dp[i]=minj<idp[j]+x[i]×(sump[i]sump[j])sum[i]+sum[j]+c[i]

对于两个转移状态 j1,j2 ,如果 j2 优与 j1 可得:

dp[j2]x[i]×sump[j2]+sum[j2]<dp[j1]x[i]×sump[j1]+sum[j1]dp[j2]+sum[j2]dp[j1]sum[j1]<x[i]×(sump[j2]+sump[j1])dp[j2]+sum[j2]dp[j1]sum[j1]sump[j2]+sump[j1]<x[i]

dp[j]+sum[j] 看作 y[j]sump[j] 看作 x[j] 后,剩余斜率优化过程与上面两题相同。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇