NOIP复健计划——动态规划

树形DP

[POI2011] DYN-Dynamite

二分KKK

check(mid):
能否选出mmm个点,使得 ∀i为关键点,Minjisselected{dis(i,j)}≤mid\forall i为关键点,Min_{j\ is\ selected}\{dis(i,j)\}\leq mid∀i为关键点,Minj is selected​{dis(i,j)}≤mid

进一步转化问题:
一棵树上选 tottottot 个点,使得∀i为关键点,Minjisselected{dis(i,j)}≤mid\forall i为关键点,Min_{j\ is\ selected}\{dis(i,j)\}\leq mid∀i为关键点,Minj is selected​{dis(i,j)}≤mid,最小化 tottottot。若tot≤mtot\leq mtot≤m则 check(mid) 为 true,否则 check(mid) 为 false。

定义点iii被点jjj覆盖,当且仅当disi,j≤middis_{i,j}\leq middisi,j​≤mid
假设当前考虑到以xxx为根的子树。
对于在xxx子树内的关键点,它们要么被xxx子树内的点覆盖,要么还等着被xxx子树外的点覆盖。
对于第二种情况,我们需要把问题留到考虑xxx的祖先时再去解决。

设fxf_xfx​表示xxx子树内未被覆盖点到xxx的最远距离,
gxg_xgx​表示xxx子树内被选择点到xxx的最近距离。
初值:fx=−∞,gx=∞f_{x}=-\infty,g_{x}=\inftyfx​=−∞,gx​=∞
转移:fx=max⁡{fy+1}f_x=\max \{f_y+1\}fx​=max{fy​+1},gx=min⁡{fy+1}g_x=\min\{f_y+1\}gx​=min{fy​+1}
特判:
若fx+gx≤midf_x+g_x\leq midfx​+gx​≤mid,则xxx子树内所有点都已经被覆盖,fx←−∞f_x\leftarrow -\infinfx​←−∞
若fx=midf_x=midfx​=mid,则xxx一定要选,fx←−∞,gx←0,tot++f_x\leftarrow -\infin,g_x\leftarrow 0,tot++fx​←−∞,gx​←0,tot++
若gx>midandx为关键点g_x>mid\ and\ x为关键点gx​>mid and x为关键点,把问题留给xxx的父亲解决,fx←max(fx,0)f_x\leftarrow max(f_x,0)fx​←max(fx​,0)
Code

重建道路

设f[i][j]f[i][j]f[i][j]表示以iii为根的子树,保留jjj个点(包括自己),删去的最小边数
初始化:f[i][1]=son[i]f[i][1]=son[i]f[i][1]=son[i](son[i]son[i]son[i]表示iii有几个儿子)
转移:f[u][j]=max{f(u,j−k)+f(v,k)−1}f[u][j]=max\{f(u,j-k)+f(v,k)-1\}f[u][j]=max{f(u,j−k)+f(v,k)−1}(−1是因为v和u之间相连的那一条边不删)

注意:我们要获得的子树的根并不一定要是整棵树的根节点
Code

城市环路

基环树
如果这道题是出在树上,那就是最大独立集的裸题
设f[i][1/0]f[i][1/0]f[i][1/0]表示选/不选iii ,以iii为根的子树的最大贡献
f[u][1]=∑v∈sonuf[v][0]f[u][1]=\sum_{v\in son_u}f[v][0]f[u][1]=∑v∈sonu​​f[v][0]
f[u][0]=∑v∈sonumax(f[v][0],f[v][1])f[u][0]=\sum_{v\in son_u}max(f[v][0],f[v][1])f[u][0]=∑v∈sonu​​max(f[v][0],f[v][1])

考虑在基环树上怎么做:
法一:强制断边
首先把环找出来
对于环上一对相邻点(x,y)(x,y)(x,y),根据题意,x,yx,yx,y不能同时选

  1. 强制xxx不选,此时yyy可选可不选,断掉边(x,y)(x,y)(x,y)无影响。断边后做树形dp,f[x][0]f[x][0]f[x][0]即为此情况下的答案
  2. 强制yyy不选,此时xxx可选可不选,断掉边(x,y)(x,y)(x,y)无影响。断边后做树形dp,f[y][0]f[y][0]f[y][0]即为此情况下的答案
  3. 最终答案=max(f[x][0],f[y][0])max(f[x][0],f[y][0])max(f[x][0],f[y][0])

Code
法二:树形dp+环形dp
博客
Code

[JSOI2008]魔兽地图

这个题的特殊性在于儿子对于父亲节点是有影响的,
所以用f[i][j][k]f[i][j][k]f[i][j][k]表示第iii号装备,其中jjj个被祖先用来合成上层装备,花费kkk元所能获得最大的力量值。

分步转移,第一步先枚举第 iii 号装备合成多少个,第二步再合并子树贡献。
Code

[JSOI2016]最佳团体

分数规划
二分答案midmidmid,问题转化为:
给定一棵根为0的树。每点点权为Pi−mid∗SiP_i-mid *S_iPi​−mid∗Si​,选定一个点就必须选其所有祖先节点。
问能否取kkk个节点使得取出点的点权和大于零。

设dp[u][j]dp[u][j]dp[u][j]表示以uuu为根的子树,取jjj个节点所带来的最大收益
合并就是经典树形背包
Code

[USACO12FEB]Nearby Cows G

基础换根dp题
f[i][j]f[i][j]f[i][j] 表示 iii 子树内到 iii 距离为 jjj 的点的权值和
g[i][j]g[i][j]g[i][j] 表示 iii 子树外到 iii 距离为 jjj 的点的权值和
Code

CF512D Fox And Travelling

首先,在环中的点一定不会被遍历。
用类似拓扑排序的过程可以把环上的点全部扔掉,剩下的点会构成若干个有根树和无根树,其中有根树的根是树中唯一与环中的点相连的点。

先考虑有根树,设 fi,jf_{i,j}fi,j​ 表示以 iii 为根的子树中,选 jjj 个点的方案数
转移:fi,j+k=fpi,j×fson,k×(j+kk)f_{i,j+k}=fp_{i,j}\times f_{son,k}\times \binom {j+k}{k}fi,j+k​=fpi,j​×fson,k​×(kj+k​)
特别地,fi,sizi=fi,sizi−1f_{i,siz_i}=f_{i,siz_i-1}fi,sizi​​=fi,sizi​−1​(根节点必须最后删)

对于无根树,感觉可以钦定最后一个被删的是哪个点,但更简单的方法是直接对每个点为根跑一遍有根树的算法,然后发现选 iii 个点的情况在没被选的 siz−isiz-isiz−i 个点为根的时候会被统计,因此答案要除以 siz−isiz-isiz−i(如果全选是特殊情况,不需要除)

然后就是森林合并答案,就用类似合并子树的方法组合数合并就可以了
Code

CF543D Road Improvement

换根dp
根据套路,
我们设fuf_ufu​为修好以uuu为根的子树中的路的方案数
gug_ugu​为修好整棵树中除了以uuu为根的子树中的路的方案数

先考虑fuf_ufu​怎么求:
设fu,0f_{u,0}fu,0​表示uuu子树内无坏边的方案数,fu,1f_{u,1}fu,1​表示uuu子树内有坏边的方案数
fu,0=∏v∈sonufv,0,fu,1=∏v∈sonu(fv,0×2+fv,1)−1f_{u,0}=\prod_{v\in son_u} f_{v,0},f_{u,1}=\prod_{v\in son_u} (f_{v,0}\times 2+f_{v,1})-1fu,0​=∏v∈sonu​​fv,0​,fu,1​=∏v∈sonu​​(fv,0​×2+fv,1​)−1
发现fu,0=1f_{u,0}=1fu,0​=1,又考虑到fu=fu,0+fu,1f_u=f_{u,0}+f_{u,1}fu​=fu,0​+fu,1​,
所以fu=∏v∈sonu(fv+1)f_u=\prod_{v\in son_u}(f_v+1)fu​=∏v∈sonu​​(fv​+1)

再考虑gug_ugu​:
gu=gfa×ffafu+1+1=gfa×∏x∈sonfa,x≠u(fx+1)+1g_u=\frac{g_{fa}\times f_{fa}}{f_u+1}+1=g_{fa}\times\prod_{x\in son_{fa},x\not=u}(f_x+1)+1gu​=fu​+1gfa​×ffa​​+1=gfa​×∏x∈sonfa​,x=u​(fx​+1)+1
因为逆元不保证存在,所以要记录前缀积和后缀积来避免除法
Code

CF1146F Leaf Partition

博客

CF1016F Road Projects

博客

CF671D Roads in Yusland

博客

CF337D Book of Evil

经典换根dp
设f[u][0]f_[u][0]f[​u][0]表示 uuu子树内的点到uuu的最大/次大距离
g[u][0]g_[u][0]g[​u][0]表示 uuu子树外的点到uuu的最大/次大距离

CF23E Tree

博客

CF708C Centroids

博客

其他DP

[WC2008] 游览计划

斯坦纳树
模板

斯坦纳树问题:

给出一个有 nnn 个点 mmm 条边的有权无向图,然后选定 kkk 个点,让你求出使这 kkk 个点联通所需的最小代价

求解:

首先,答案的子图一定是树

设 dp[i][S]dp[i][S]dp[i][S] 表示以 iii 为根的一棵树,包含集合 SSS 中所有点的最小代价。

转移:

对于 iii 的度数为 1 的情况,可以考虑枚举树上与 iii 相邻的点 jjj,则
dp(j,s)+w(j,i)−>dp(i,s)dp(j,s)+w(j,i)−>dp(i,s)dp(j,s)+w(j,i)−>dp(i,s)
对于 iii 的度数大于 1 的情况,可以划分成几个子树考虑,则
dp(i,T)+dp(i,S−T)−>dp(i,S)(T⊆S)dp(i,T)+dp(i,S−T)−>dp(i,S)(T\subseteq S)dp(i,T)+dp(i,S−T)−>dp(i,S)(T⊆S)

对于第1种转移,可以想到最短路模型的三角形不等式,对于每一个 SSS ,将图做一次松弛操作即可。具体可以用 dijkstra 或 spfa 实现。
对于第2种转移,枚举子集即可。

如何优秀的枚举子集:
一个非常trivial的做法:

for(int sta=0;sta<=MAX;sta++){for(int s=0;s<=MAX;s++){if(s&sta==s){//to do sth}}
}

时间复杂度 O(4n)O(4^n)O(4n)
更优秀的实现:

for(int sta=0;sta<=MAX;sta++){for(int s=(sta-1)&sta;s;s=(s-1)&sta){//to do sth}
}

时间复杂度 ∑sta2∣∣sta∣∣=∑i=0nCni2i=3n\sum_{sta}2^{||sta||}=\sum_{i=0}^{n}C_{n}^{i}2^i=3^n∑sta​2∣∣sta∣∣=∑i=0n​Cni​2i=3n
Code

[COCI2011-2012 6]

SOS DP+容斥

首先发现 mmm 很小,于是直接对于每一个箱子状压
于是问题转化为选若干个数使它们按位或为全集
继续转化一下,把每个箱子取个反,问题就变成了选若干个数使它们按位与为空集

设 g[S]g[S]g[S] 为有多少种选数方案使SSS为选出数的按位与的子集
答案为∑S(−1)∣∣S∣∣g[S]\sum_{S}(-1)^{||S||}g[S]∑S​(−1)∣∣S∣∣g[S]

设 f[S]f[S]f[S] 为有多少个箱子,使SSS为其代表的数A[i]A[i]A[i]的子集
g[S]=2f[S]−1g[S]=2^{f[S]}-1g[S]=2f[S]−1

求 f[S]f[S]f[S]:
法一:直接枚举子集

for(int sta=0;sta<=MAX;sta++){for(int s=(sta-1)&sta;s;s=(s-1)&sta){//to do sth}
}

时间复杂度 O(3m)O(3^m)O(3m)
法二:高维前缀和解决这类子集问题

for(int i=0;i<m;i++){for(int s=0;s<(1<<m);s++){if(s&(1<<i)){f[s^(1<<i)]+=f[s];//与标准sos dp方程相比,这里的语句反过来了}}
}

时间复杂度 O(m2m)O(m2^m)O(m2m)
这种方法又称为SOS DP:博客1 博客2
Code

[CF383E] Vowels

法一:​SOS DP
正难则反,考虑统计不合法单词数
让每个单词对应一个状态AAA,第iii位表示第iii个字母是否在单词中出现(1为出现)
记元音字母集的补集为BBB
则不合法单词对应的AAA均为BBB的子集
设f[S]f[S]f[S]表示有多少个单词,其对应的AAA为SSS的子集,可以用sos dp求出:

for(int i=0;i<m;i++){for(int s=0;s<(1<<m);s++){if(s&(1<<i)){f[s]+=f[s^(1<<i)];//标准sos dp方程}}
}

答案即为(n−f[S])2(n-f[S])^2(n−f[S])2的异或和
Code

法二:SOS DP+容斥
设g[S]g[S]g[S]为元音集合为SSS时的合法单词数
设f[s]f[s]f[s]为有多少个单词,使sss为其代表的AAA的子集
即f[s]=∑i=1n[s∈wordi]f[s]=\sum_{i=1}^{n}[s\in word_i]f[s]=∑i=1n​[s∈wordi​]
g[S]=∑s∈S(−1)∣∣s∣∣+1f[s]g[S]=\sum_{s\in S}(-1)^{||s||+1}f[s]g[S]=∑s∈S​(−1)∣∣s∣∣+1f[s]
但是这样做的时间复杂度是O(324)O(3^{24})O(324),会TLE,所以我们转换一下:
令f[s]=∑i=1n(−1)∣∣s∣∣+1[s∈wordi]f[s]=\sum_{i=1}^{n}(-1)^{||s||+1}[s\in word_i]f[s]=∑i=1n​(−1)∣∣s∣∣+1[s∈wordi​]
则g[S]=∑s∈Sf[s]g[S]=\sum_{s\in S}f[s]g[S]=∑s∈S​f[s]
求f[s]f[s]f[s]的复杂度是O(n⋅23)O(n\cdot 2^3)O(n⋅23)(对于每一个单词,枚举其子集)
求g[S]g[S]g[S]的复杂度是O(24⋅224)O(24\cdot 2^{24})O(24⋅224)(sos dp)
Code

[CF449D] Jzzhu and Numbers

法一:SOS DP+容斥
同COCI2011-2012 6
设 g[S]g[S]g[S] 为有多少种选数方案使SSS为选出数的按位与的子集
答案为∑S(−1)∣∣S∣∣g[S]\sum_{S}(-1)^{||S||}g[S]∑S​(−1)∣∣S∣∣g[S]
设 f[S]f[S]f[S] 为有多少个箱子,使SSS为其代表的数A[i]A[i]A[i]的子集
g[S]=2f[S]−1g[S]=2^{f[S]}-1g[S]=2f[S]−1
Code

法二:FWT
设dp[i][s]dp[i][s]dp[i][s]为从前iii个数中选择,有多少种选数方案使选出数的按位与为sss
dp[i][j]=dp[i−1][j]+∑k&a[i]==jdp[i−1][k]dp[i][j]=dp[i-1][j]+\sum_{k\&a[i]==j}dp[i-1][k]dp[i][j]=dp[i−1][j]+∑k&a[i]==j​dp[i−1][k]
dp[s&a[i]]+=dp[s]dp[s\&a[i]]+=dp[s]dp[s&a[i]]+=dp[s]
发现这个柿子本质上就是一个和卷积,可以用FWT解决
博客

[CF348D] Turtles

LGV引理
Code

[USACO20OPEN]Exercise G

循环了几次可以回到原地,当且仅当形成了一个环,假设每个环的长度是 aia_iai​,那么k=lcm⁡aik=\operatorname{lcm}a_ik=lcmai​

又知道 lcm⁡ai\operatorname{lcm}a_ilcmai​ 其实就是将所有aia_iai​分解质因数,然后取每个质数的最高次幂乘起来,
所以我们可以想到枚举素数来做dp

设 f[i][j]f[i][j]f[i][j] 表示前 iii 个素数总和为 jjj 的所有 KKK 的总和

枚举第 iii 个素数的幂进行转移:
f[i][j]=∑f[i−1][j−pik]×pikf[i][j]=\sum f[i-1][j-p_i^k]\times p_i^kf[i][j]=∑f[i−1][j−pik​]×pik​

可以滚动数组减掉一维
Code

双倍经验:[SCOI2009]游戏 博客

OSU!

设dp[i]dp[i]dp[i]表示到了第iii个位置的期望得分,
f[l]f[l]f[l]表示第iii个位置之前有长度为lll的连续1串的概率,
p[i]p[i]p[i]表示iii为1的概率,
则有转移:
dp[i]=dp[i−1]+p[i]∑lf[l]((l+1)3−l3)=dp[i−1]+p[i]∑lf[l](3l2+3l+1)dp[i]=dp[i-1]+p[i]\sum_lf[l]((l+1)^3-l^3)=dp[i-1]+p[i]\sum_l f[l](3l^2+3l+1)dp[i]=dp[i−1]+p[i]∑l​f[l]((l+1)3−l3)=dp[i−1]+p[i]∑l​f[l](3l2+3l+1)

于是考虑维护
El=∑lf[l]⋅lE_l=\sum_lf[l]\cdot lEl​=∑l​f[l]⋅l
El2=∑lf[l]⋅l2E_{l^2}=\sum_lf[l]\cdot l^2El2​=∑l​f[l]⋅l2

则总转移方程为:
El[i]=p[i]∑lf[l](l+1)=p[i](El[i−1]+∑lf[l])=p[i](El[i−1]+1)E_l[i]=p[i]\sum_lf[l](l+1)=p[i](E_l[i-1]+\sum_lf[l])=p[i](E_l[i-1]+1)El​[i]=p[i]∑l​f[l](l+1)=p[i](El​[i−1]+∑l​f[l])=p[i](El​[i−1]+1)
El2[i]=p[i]∑lf[l](l2+2l+1)=p[i](El2[i−1]+2El[i−1]+1)E_{l^2}[i]=p[i]\sum_lf[l](l^2+2l+1)=p[i](E_{l^2}[i-1]+2E_{l}[i-1]+1)El2​[i]=p[i]∑l​f[l](l2+2l+1)=p[i](El2​[i−1]+2El​[i−1]+1)
dp[i]=dp[i−1]+p[i](3El2[i−1]+3El[i−1]+1)dp[i]=dp[i-1]+p[i](3E_{l^2}[i-1]+3E_l[i-1]+1)dp[i]=dp[i−1]+p[i](3El2​[i−1]+3El​[i−1]+1)
Code

收集邮票

设f[i]f[i]f[i]表示已经取到了iii种邮票,要取完剩余邮票的期望次数,
ans[i]ans[i]ans[i]表示已经取到了iii种邮票,要取完剩余邮票的期望价格

f[i]=inf[i]+n−inf[i+1]+1f[i]=\frac{i}{n}f[i]+\frac{n-i}{n}f[i+1]+1f[i]=ni​f[i]+nn−i​f[i+1]+1
⇒f[i]=f[i+1]+nn−i\Rightarrow f[i]=f[i+1]+\frac{n}{n-i}⇒f[i]=f[i+1]+n−in​
ans[i]=in(ans[i]+f[i]+1)+n−in(ans[i+1]+f[i+1]+1)ans[i]=\frac{i}{n}(ans[i]+f[i]+1)+\frac{n-i}{n}(ans[i+1]+f[i+1]+1)ans[i]=ni​(ans[i]+f[i]+1)+nn−i​(ans[i+1]+f[i+1]+1)
⇒ans[i]=ans[i+1]+f[i+1]+in−if[i]+nn−i\Rightarrow ans[i]=ans[i+1]+f[i+1]+\frac{i}{n-i}f[i]+\frac{n}{n-i}⇒ans[i]=ans[i+1]+f[i+1]+n−ii​f[i]+n−in​

注意:ans[i]≠(f[i]+1)f[i]2ans[i]\not=\frac{(f[i]+1)f[i]}{2}ans[i]=2(f[i]+1)f[i]​,理由如下:
ans[i]=∑cntpcnt(cnt+1)cnt2ans[i]=\sum_{cnt}p_{cnt}\frac{(cnt+1)cnt}{2}ans[i]=∑cnt​pcnt​2(cnt+1)cnt​
(f[i]+1)f[i]2=(∑cntpcntcnt+1)∑cntpcntcnt2\frac{(f[i]+1)f[i]}{2}=\frac{(\sum_{cnt}p_{cnt}cnt+1)\sum_{cnt}p_{cnt}cnt}{2}2(f[i]+1)f[i]​=2(∑cnt​pcnt​cnt+1)∑cnt​pcnt​cnt​
Code

[CF605E] Intergalaxy Trips

设f[i]f[i]f[i]为从iii走到nnn的期望耗时

考虑转移:
首先,我们一定不会找比当前点更劣的点转移,因为这还没有留在原地划算
其次,如果可以转移,那么转移到某点的唯一可能是比它优的点都转移不到
f[i]=1+f[i]∏j,fj<fi(1−pi,j)+∑j,fj<fif[j]pi,j∏k,pk<pj(1−pi,k)f[i]=1+f[i]\prod_{j,f_j<f_i}(1-p_{i,j})+\sum_{j,f_j<f_i}f[j]p_{i,j}\prod_{k,p_k<p_j}(1-p_{i,k})f[i]=1+f[i]∏j,fj​<fi​​(1−pi,j​)+∑j,fj​<fi​​f[j]pi,j​∏k,pk​<pj​​(1−pi,k​)

⇒f[i]=1+∑j,fj<fif[j]pi,j∏k,pk<pj(1−pi,k)1−∏j,fj<fi(1−pi,j)\Rightarrow f[i]=\frac{1+\sum_{j,f_j<f_i}f[j]p_{i,j}\prod_{k,p_k<p_j}(1-p_{i,k})}{1-\prod_{j,f_j<f_i}(1-p_{i,j})}⇒f[i]=1−∏j,fj​<fi​​(1−pi,j​)1+∑j,fj​<fi​​f[j]pi,j​∏k,pk​<pj​​(1−pi,k​)​

实现:朴素版Dijkstra
博客
Code

常见优化与综合运用

[CF939F] Cutlet

设 dp[i][j]dp[i][j]dp[i][j] 表示前 rir_iri​ 分钟,把现在煎的面叫做正面,背面煎了 jjj 分钟的最小翻面次数
显然只会在一个区间至多翻 2 次:
不翻面,dp[i][j]=dp[i−1][j]dp[i][j]=dp[i-1][j]dp[i][j]=dp[i−1][j]
翻了一次,枚举正面煎了 kkk 秒,dp[i][j]=min(dp[i−1][r−j−k]+1)dp[i][j] = min(dp[i-1][r-j-k] + 1)dp[i][j]=min(dp[i−1][r−j−k]+1)
翻了两次,枚举背面煎了 kkk 秒,dp[i][j]=min(dp[i−1][j−k]+2)dp[i][j] = min(dp[i-1][j-k] + 2)dp[i][j]=min(dp[i−1][j−k]+2)
在这里插入图片描述
分别用单调队列维护即可

一句话解释单调队列优化dp:如果一个人比你年轻,还比你强,那你就永远打不过他了.jpg

Code

[CF311B] Cats Transport

因为对于任意一只猫,我们都可以直接算出如果有一个人要恰好接走它,需要在哪一时刻出发,我们设第i只猫对应的这个时刻为tit_{i}ti​

对于第iii只猫,我们定义tit_{i}ti​表示如果有人在tit_{i}ti​时刻出发,此猫无须等待即可被接走
题目转化为:
现有ppp个人,要求为每个人指定一个出发时间aja_jaj​,最小化∑i=1m(xi−ti)\sum_{i=1}^{m}(x_i-t_i)∑i=1m​(xi​−ti​)(xi=Minaj≥ti{aj}x_i=Min_{a_j\geq t_i}\{a_j\}xi​=Minaj​≥ti​​{aj​})

观察到每个人的出发时间aja_jaj​必是tit_iti​中的一个
那么假设第xxx个人的出发时间是tit_iti​,第x−1x-1x−1个人的出发时间是tjt_jtj​,
则第xxx个人会接走第j+1j+1j+1到第iii只猫
题目转化为:
现有ppp个人,要求为每个人选一只猫bjb_jbj​,最小化∑j=1p∑i=bj−1+1bj(tbj−ti)\sum_{j=1}^{p}\sum_{i=b_{j-1}+1}^{b_j}(t_{b_j}-t_i)∑j=1p​∑i=bj−1​+1bj​​(tbj​​−ti​)

设f[i][j]f[i][j]f[i][j]表示考虑到第iii个人,这个人选择了第jjj只猫的最小代价
记s[i]=∑k=1itks[i]=\sum_{k=1}^{i}t_ks[i]=∑k=1i​tk​
则f[i][j]f[i][j]f[i][j]有转移式:
f[i][j]=Min{f[i−1][k]+tj(j−k)−(s[j]−s[k])}f[i][j]=Min\{f[i-1][k]+t_j(j-k)-(s[j]-s[k])\}f[i][j]=Min{f[i−1][k]+tj​(j−k)−(s[j]−s[k])}

用斜率优化求f[i][j]f[i][j]f[i][j]:
f[i][j]=f[i−1][k]+tj(j−k)−(s[j]−s[k])f[i][j]=f[i-1][k]+t_j(j-k)-(s[j]-s[k])f[i][j]=f[i−1][k]+tj​(j−k)−(s[j]−s[k])
⟺f[i−1][k]+s[k]=tj⋅k+f[i][j]+s[j]−tjj\iff f[i-1][k]+s[k]=t_j\cdot k+f[i][j]+s[j]-t_jj⟺f[i−1][k]+s[k]=tj​⋅k+f[i][j]+s[j]−tj​j
把f[i−1][k]+s[k]f[i-1][k]+s[k]f[i−1][k]+s[k]看成yyy,kkk看成xxx,tjt_jtj​看成kkk,f[i][j]+s[j]−tjjf[i][j]+s[j]-t_jjf[i][j]+s[j]−tj​j看成bbb
现要找到一个点P(k,f[i−1][k]+s[k])P(k,f[i-1][k]+s[k])P(k,f[i−1][k]+s[k])使得bbb最小
维护一个下凸壳,并在凸包上找最优决策点PPP即可
因为kkk单增,所以可以用单调队列实现
Code

[NOI2009] 诗人小G

设fif_ifi​表示对前iii个句子排版后的最小不协调度
记si=∑j=1i(lenj+1)s_i=\sum_{j=1}^i(len_j+1)si​=∑j=1i​(lenj​+1),则
fi=minj=0i−1{fj+∣si−sj−1−L∣P}f_i=min_{j=0}^{i-1}\{f_j+|s_i-s_j-1-L|^P\}fi​=minj=0i−1​{fj​+∣si​−sj​−1−L∣P}
这条转移式是有决策单调性的

感性证明:
记hj(x)=∣x−sj−1−L∣Ph_j(x)=|x-s_j-1-L|^Phj​(x)=∣x−sj​−1−L∣P
不难看出hjh_jhj​关于直线x=sj+1+Lx=s_j+1+Lx=sj​+1+L对称

对于x>sj+1+Lx>s_j+1+Lx>sj​+1+L的部分:
hj(x)=(x−sj−1−L)Ph_j(x)=(x-s_j-1-L)^Phj​(x)=(x−sj​−1−L)P
hj′(x)=P(x−sj−1−L)P−1h_j'(x)=P(x-s_j-1-L)^{P-1}hj′​(x)=P(x−sj​−1−L)P−1
所以hj′(x)h_j'(x)hj′​(x)在(sj+1+L,+∞)(s_j+1+L,+\infin)(sj​+1+L,+∞)上单增且恒大于0

对于x<sj+1+Lx<s_j+1+Lx<sj​+1+L的部分:
根据对称性,hj′(x)h_j'(x)hj′​(x)在(−∞,sj+1+L)(-\infin,s_j+1+L)(−∞,sj​+1+L)上同样单增且恒小于0

又因为函数连续,所以hj′(x)h_j'(x)hj′​(x)在R\RR上单增

又因为hj1(x)=hj(x+sj−sj1)h_{j_1}(x)=h_j(x+s_j-s_{j_1})hj1​​(x)=hj​(x+sj​−sj1​​),即不同的hj(x)h_j(x)hj​(x)之间可以通过平移得到,
所以∀j1≠j2\forall j_1\not=j_2∀j1​=j2​,hj1(x)h_{j_1}(x)hj1​​(x)与hj2(x)h_{j_2}(x)hj2​​(x)最多一个交点
在这里插入图片描述
意会一下吧
所以 fff 的转移式满足决策单调性
%%%FlashHu大佬

严谨证明:
证明w(j,i)=∣si−sj−1−L∣Pw(j,i)=|s_i-s_j-1-L|^Pw(j,i)=∣si​−sj​−1−L∣P满足四边形不等式,本蒟蒻不会
贴个博客吧
Code

[CF868F] Yet Another Minimization Problem

设dpi,jdp_{i,j}dpi,j​表示将序列的前iii个数划分成jjj段所需要的最小费用,
设wl,rw_{l,r}wl,r​表示将lll到rrr划分成一段所需要的花费
显然有转移方程:dpi,j=min{dpx,j−1+wx+1,i}dp_{i,j} =min\{dp_{x,j-1}+w_{x+1,i}\}dpi,j​=min{dpx,j−1​+wx+1,i​}

决策单调性证明:
法一(四边形不等式):
要证dpdpdp的转移具有决策单调性
即证∀a<b,w(a,b)+w(a+1,b+1)≤w(a,b+1)+w(a+1,b)\forall a<b,w(a,b)+w(a+1,b+1)\leq w(a,b+1)+w(a+1,b)∀a<b,w(a,b)+w(a+1,b+1)≤w(a,b+1)+w(a+1,b)
即证∀a<b,w(a,b)−w(a+1,b)≤w(a,b+1)−w(a+1,b+1)\forall a<b,w(a,b)-w(a+1,b)\leq w(a,b+1)-w(a+1,b+1)∀a<b,w(a,b)−w(a+1,b)≤w(a,b+1)−w(a+1,b+1)
即把区间从[a+1,b][a+1,b][a+1,b]拓到[a,b][a,b][a,b]的增量≤\leq≤把区间从[a+1,b+1][a+1,b+1][a+1,b+1]拓到[a,b+1][a,b+1][a,b+1]的增量
该式显然正确,因为在区间中增加一个元素,它对答案的贡献与区间内与它值相同的元素数量有关
法二:
记cx[i]c_x[i]cx​[i]为区间[1,i][1,i][1,i]中值为jjj的元素个数
hj(i)=w(j+1,i)=∑x(cx[i]−cx[j])(cx[i]−cx[j]−1)2h_j(i)=w(j+1,i)=\sum_{x}\frac{(c_x[i]-c_x[j])(c_x[i]-c_x[j]-1)}{2}hj​(i)=w(j+1,i)=∑x​2(cx​[i]−cx​[j])(cx​[i]−cx​[j]−1)​
因为(cx[i]−cx[j])(cx[i]−cx[j]−1)2\frac{(c_x[i]-c_x[j])(c_x[i]-c_x[j]-1)}{2}2(cx​[i]−cx​[j])(cx​[i]−cx​[j]−1)​的导函数单增,所以合起来就可以得出hj′(i)h_j'(i)hj′​(i)单增
结合图像可以证明dpdpdp的转移具有决策单调性

实现:
因为cost(j,i)cost(j,i)cost(j,i)不好快速计算,不适合用二分栈来做,所以这题是用分治实现的
Code

[SDOI2016]征途

高中数学告诉我们:s2=x2‾−x‾2s^2=\overline {x^2}-{\overline x}^2s2=x2−x2
所以m2s2=m∑vi2−(∑vi)2m^2s^2=m\sum v_i^2-(\sum v_i)^2m2s2=m∑vi2​−(∑vi​)2
−(∑vi)2-(\sum v_i)^2−(∑vi​)2为定值,我们只要令∑vi2\sum v_i^2∑vi2​最小即可
设f[i][j]f[i][j]f[i][j]表示把前iii段路分为jjj天走,∑k=1jvk2\sum_{k=1}^{j}v_k^2∑k=1j​vk2​的最小值
记sis_isi​表示前iii段路的长度和
则f[i][j]f[i][j]f[i][j]有转移式:f[i][j]=min{f[x][j−1]+(si−sx)2}f[i][j]=min\{f[x][j-1]+(s_i-s_x)^2\}f[i][j]=min{f[x][j−1]+(si​−sx​)2}

斜率优化:
f[i][j]=f[x][j−1]+(si−sx)2f[i][j]=f[x][j-1]+(s_i-s_x)^2f[i][j]=f[x][j−1]+(si​−sx​)2
⟺2sisx+f[i][j]−si2=f[x][j−1]+sx2\iff 2s_is_x+f[i][j]-s_i^2=f[x][j-1]+s_x^2⟺2si​sx​+f[i][j]−si2​=f[x][j−1]+sx2​
把2si2s_i2si​看成kkk,sxs_xsx​看成xxx,f[i][j]−si2f[i][j]-s_i^2f[i][j]−si2​看成bbb,f[x][j−1]+sx2f[x][j-1]+s_x^2f[x][j−1]+sx2​看成yyy
找最优决策点即找到点(sx,f[x][j−1]+sx2)(s_x,f[x][j-1]+s_x^2)(sx​,f[x][j−1]+sx2​)使得bbb最小
Code

[HNOI2011]数学作业

容易得到递推式:f[n]=f[n−1]×10len(n)+nmodmf[n]=f[n-1]\times 10^{len(n)}+n \mod mf[n]=f[n−1]×10len(n)+nmodm
构造转移矩阵:
[f[n]n1]=[f[n−1]n−11]×[10len(n)00110111]\begin{bmatrix} f[n]&n&1\end{bmatrix}=\begin{bmatrix}f[n-1]&n-1&1\end{bmatrix}\times\begin{bmatrix}10^{len(n)}&0&0\\1&1&0\\1&1&1\end{bmatrix} [f[n]​n​1​]=[f[n−1]​n−1​1​]×⎣⎡​10len(n)11​011​001​⎦⎤​
如果不是10len(n)10^{len(n)}10len(n)这个奇怪的变量,这道题已经做完了
那我们干脆把10len(n)10^{len(n)}10len(n)变成常量:枚举位数,对每一个位数做一次矩阵快速幂

[USACO07NOV]Cow Relays G

经典结论:
用矩阵AAA表示有向图GGG的连通情况(Ai,j=1A_{i,j}=1Ai,j​=1表示GGG中存在边i→ji\to ji→j)
那么从sss到ttt经过kkk条边的路径数=(Ak)s,t(A^k)_{s,t}(Ak)s,t​

拓展到本题:
我们定义一种新运算∗*∗:
[a1,1a1,2⋯a1,ma2,1a2,2⋯a2,m⋮⋮⋱⋮an,1an,2⋯an,m]∗[b1,1b1,2⋯b1,nb2,1b2,2⋯b2,n⋮⋮⋱⋮bm,1bm,2⋯bm,n]=[c1,1c1,2⋯c1,nc2,1c2,2⋯c2,n⋮⋮⋱⋮cn,1cn,2⋯cn,n]\begin{bmatrix} a_{1,1}&a_{1,2}&\cdots&a_{1,m}\\a_{2,1}&a_{2,2}&\cdots&a_{2,m}\\\vdots&\vdots&\ddots&\vdots\\a_{n,1}&a_{n,2}&\cdots&a_{n,m}\end{bmatrix} * \begin{bmatrix} b_{1,1}&b_{1,2}&\cdots&b_{1,n}\\b_{2,1}&b_{2,2}&\cdots&b_{2,n}\\\vdots&\vdots&\ddots&\vdots\\b_{m,1}&b_{m,2}&\cdots&b_{m,n}\end{bmatrix} =\begin{bmatrix} c_{1,1}&c_{1,2}&\cdots&c_{1,n}\\c_{2,1}&c_{2,2}&\cdots&c_{2,n}\\\vdots&\vdots&\ddots&\vdots\\c_{n,1}&c_{n,2}&\cdots&c_{n,n}\end{bmatrix} ⎣⎡​a1,1​a2,1​⋮an,1​​a1,2​a2,2​⋮an,2​​⋯⋯⋱⋯​a1,m​a2,m​⋮an,m​​⎦⎤​∗⎣⎡​b1,1​b2,1​⋮bm,1​​b1,2​b2,2​⋮bm,2​​⋯⋯⋱⋯​b1,n​b2,n​⋮bm,n​​⎦⎤​=⎣⎡​c1,1​c2,1​⋮cn,1​​c1,2​c2,2​⋮cn,2​​⋯⋯⋱⋯​c1,n​c2,n​⋮cn,n​​⎦⎤​
其中ci,j=Mink=1m{ai,k+bk,j}c_{i,j}=Min_{k=1}^m{}\{a_{i,k}+b_{k,j}\}ci,j​=Mink=1m​{ai,k​+bk,j​}
因为∗*∗运算满足结合律,所以A∗A∗A∗⋯∗AA*A*A*\cdots *AA∗A∗A∗⋯∗A仍然可以用快速幂求得

在这种新运算下,如果初始矩阵中Ai,jA_{i,j}Ai,j​表示iii到jjj的最小距离
那么从sss到ttt经过kkk条边的最短路径长度=(Ak)s,t(A^k)_{s,t}(Ak)s,t​(这里的AkA^kAk表示kkk个AAA相∗*∗)
博客

[SCOI2014]方伯伯的玉米田

首先本题需要确定一个事实:
每一次的拔高操作区间右端点一定是最右边的玉米

设f[i][j]f[i][j]f[i][j]表示以 iii 结尾,iii 这个点已经被 jjj 个拔高区间覆盖过,所能得到的最长不下降序列长度
f[i][j]=max{f[k][l]}+1(1≤k<i,0≤l≤j,h[i]+j≥h[l][k]f[i][j]=max\{f[k][l]\}+1(1\leqk<i,0\leq l\leq j,h[i]+j\geq h[l][k]f[i][j]=max{f[k][l]}+1(1≤k<i,0≤l≤j,h[i]+j≥h[l][k]

用数据结构优化转移即可
Code

[NOIP2018 提高组] 保卫王国

博客
Code

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:
http://www.tpcf.cn/news/319792.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【每日一题】7月6日精讲—平衡二叉树

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 平衡二叉树&#xff0c;顾名思义就…

【DP】晨练计划(ybtoj)

正题 ybtoj 题目大意 给你n个时间点 在第i个时间点跑步有aia_iai​点贡献&#xff0c;但会加一点疲惫值&#xff0c;疲惫值不能超过m 当前疲惫值为x&#xff0c;那么你可以花x点时间来清空疲惫值&#xff0c;当然也可以啥都不干 问你第n个时间后疲惫值为0的最大贡献 解题思…

MATLAB灰色预测

一.灰色预测 1.灰色系统下的灰色预测 <1>什么是灰色系统&#xff1f; 所谓的灰色系统其实就是夹杂在白色系统和黑色系统之中的一种系统&#xff0c;而白色系统就是全部信息已知的系统&#xff0c;黑色系统就是全部信息未知的系统。所以&#xff0c;夹在这两种系统中间…

ASP.NET Core 中的依赖注入

什么是依赖注入软件设计原则中有一个依赖倒置原则&#xff08;DIP&#xff09;&#xff0c;为了更好的解耦&#xff0c;讲究要依赖于抽象&#xff0c;不要依赖于具体。而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖注入(DI)。什么是依…

P4357-[CQOI2016]K远点对【K-Dtree】

正题 题目链接:https://www.luogu.com.cn/problem/P4357 题目大意 平面上给出nnn个点&#xff0c;求第kkk远的点对距离。 解题思路 K-Dtree\text{K-Dtree}K-Dtree的模板题&#xff0c;但是这里只有二维&#xff0c;大概是每次根据一个维度把nnn个点分成两半像线段树一样丢到下…

【每日一题】7月7日题目精讲—最短路

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 给一个连通图&#xff0c;每次询问…

【dfs】栅栏的木料(2012特长生 T4)

题目大意 给你n个木板&#xff0c;给你这些木板的长度&#xff0c;你可以把这些木板切开&#xff0c;现在有m个木料&#xff0c;问你最多可以切出多少个木料 解题思路 可以dfs枚举每个木料用哪个木板来切 但这样显然会超时&#xff0c;那么考虑剪枝 1.对于一些木板&#xf…

【c++算法刷题笔记】——洛谷1

2020/2/14-2/16 1. 循环提取一个数的每一位数字 while (d > 0) //d0跳出循环 {xd%10; //x每次为d的个位数 d d / 10; //相当于d每次舍去个位数 }2. cnew创建动态二维数组 int *anew int[n]; //创建动态一维数组 int(* a)[2…

【活动(广州)】office365的开发者训练营

Office 365每月有超过1亿的商业活跃用户&#xff0c;是现有最大的生产力服务。Office 365为开发人员提供了一个令人难以置信的机会&#xff0c;包括业务关键数据和数百万用户&#xff0c;以及一个旨在让人们保持工作流程的平台。作为一名开发人员&#xff0c;您可以使用每天使用…

P5325-[模板]Min_25筛

正题 题目链接:https://www.luogu.com.cn/problem/P5325 题目大意 定义一个积性函数满足f(pk)pk(pk−1)f(p^k)p^k(p^k-1)f(pk)pk(pk−1) 求∑i1nf(i)\sum_{i1}^nf(i)∑i1n​f(i) 解题思路 首先我们可以把f(pk)f(p^k)f(pk)是质数的情况拆成一个222阶的多项式f(x)x2−xf(x)x^2…

牛客网【每日一题】7月8日 Alliances

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 5秒&#xff0c;其他语言10秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 树国是一个有n个城市的国家&#xff0c;城市编号…

【bfs】廉价最短路径(2013特长生 T4)

题目大意 给你一个图&#xff0c;每条边有一个代价&#xff0c;让你求0到1在最短路径的前提下的最小代价 解题思路 bfs同时求个最代价 代码 #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #de…

Ocelot简易教程(四)之请求聚合以及服务发现

上篇文章给大家讲解了Ocelot的一些特性并对路由进行了详细的介绍&#xff0c;今天呢就大家一起来学习下Ocelot的请求聚合以及服务发现功能。希望能对大家有所帮助。作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9695639.html请求聚合Ocelot允…

邓公数据结构C++语言版学习笔记1

1. 对于计算幂2n2^n2n的算法优化 暴力算法时间复杂度O(n)O(n)O(n) __int64 power2BF_I(int n) //幂函数2^n算法&#xff08;蛮力迭代版&#xff09;&#xff0c;n > 0{ __int64 pow 1; //O(1)&#xff1a;累积器刜始化为2^0while (0 < n --) //O(n)&#xff1a;迭代n轮…

【每日一题】7月9日题目 Color

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K Special Judge, 64bit IO Format: %lld文章目录题目描述题解&#xff1a;代码&#xff1a;题目描述 给一个没有重边的二…

【DP】K星人的语言(2020特长生 T3)

题目大意 给你一个字符串和若干单词&#xff0c;问你最少删除多少字符使其成为若干单词连在一起的字符串 解题思路 设fif_ifi​为前i个位置的最小代价 然后枚举每个单词即可 代码 #include<cstdio> #include<cstring> #include<iostream> #include<al…

HttpClientFactory系列二:集成Polly处理瞬态故障

前言&#xff1a;最近&#xff0c;同事在工作中遇到了使用HttpClient,有些请求超时的问题&#xff0c;辅导员让我下去调研一下&#xff0c;HttpClinet的使用方式已经改成了之前博客中提到的方式&#xff0c;问题的原因我已经找到了&#xff0c;就是因为使用了伪异步&#xff0c…

Loj#6053-简单的函数【Min25筛】

正题 题目链接:https://loj.ac/p/6053 题目大意 定义一个积性函数f(pc)pxorcf(p^c)p\ xor\ cf(pc)p xor c&#xff0c;求∑i1nf(i)\sum_{i1}^nf(i)∑i1n​f(i) 解题思路 异或这个东西不太好搞&#xff0c;要考虑怎么求出ggg数组。 当ppp为质数时f(p)p−1f(p)p-1f(p)p−1&am…

邓公数据结构C++语言版学习笔记——二叉树

二叉树的遍历 一. preorder——先序遍历VLR 1. 递归先序遍历 2. 迭代先序遍历 3.先序遍历图解 二. inorder——先序遍历LVR 1. 递归中序遍历 2.迭代中序遍历 3.迭代中序遍历优化空间复杂度 <1>定义直接后继 <2>借用直接后继优化算法 解释&#xff1a;…

二分图匹配--匈牙利算法

文章目录二分图&#xff1a;匹配匈牙利算法代码&#xff1a;二分图&#xff1a; 二分图是一个无向图&#xff0c;点集分成子集X和Y&#xff0c;图中每一条边都是一边在X一边在Y 当且仅当无向图G的每一个回路次数都是偶数时&#xff08;包括0&#xff09;&#xff0c;G就是一个…