ABC217

ABC217

A

签到

B

签到

C

签到

D

有一根长度为\(L\)的木棍,有以下两个操作:

\(1.\)\(x_i\)处断开

\(2.\)回答包含\(x_i\)处的木棍的长度

解:

\(set\)二分

E

给定一个空序列,有以下三种操作:

\(1.\)在末尾添加一个字符\(x\)

\(2.\)输出首字符并删除

\(3.\)将序列升序排序

解:

\(queue\)维护序列,升序排序时将序列中的所有字符都加入小根堆

输出时优先输出小根堆内堆顶,堆为空时输出队首

F

一列\(2n(n\leq 200)\)个人,有\(m\)对友好关系,每次选择相邻的两个友好的人删掉,求删掉所有人的方案数

解:

一眼区间\(dp\)

但是计算方案数的区间\(dp\)需要特殊的统计方法保证不重不漏

要不重复就要利用当前枚举到区间的特征

枚举\(k\in[l+1,r]\),表示最后一步是由\(l,k\)配对而成

\(f[l][r]=\sum_{k=l+1}^r f[l+1][k-1]*f[k+1][r]*\dbinom{\frac{r-l+1}{2}}{\frac{k-l+1}{2}}\)

G

\(1\sim n(n\leq 5000)\)分配到\(k(k=1,2,…,n)\)个非空集合里,\(id\)号模\(m\)同余的人不能在一个集合里,有多少种分组方式?

解:

考虑没有限制时,答案为第二类斯特林数\(S_2[n][k]\)

第二类斯特林数的递推式

\[dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*j \]

其中第一部分表示第\(i\)个数字自成一组,不需要考虑限制

第二个部分表示第\(i\)个数字加入到现有的组中,只要去掉不能加入的组

\(sum[i]\)\(1\sim i-1\)中模\(m\)\(i\)同余的数的个数

\[dp[i][j]=dp[i-1][j-1]+dp[i][j]*(j-sum[i]) \]

H

小人开始时在数轴上的原点,每个时刻可以选择向左移动一步或向右移动一步

\(n(2e5)\)次操作,每次在\(t_i\)时刻\(x_i\)处出现出现一把向左或向右发射的水枪,对小人造成\(|x_i-pos|\)的伤害,如果在水枪背侧则不受伤害

求受到的最少伤害

解:

https://www.cnblogs.com/ak-dream/p/AK_DREAM127.html

这篇写得好

定义一个\(dp\)状态:\(dp_{t,x}\)表示\(t\)时刻在\(x\)处受到的最少伤害,\(F_{t,x}\)表示\(t\)时刻在\(x\)处受到的伤害

有转移方程

\[dp_{t_i,x}=F(t,x)+min\{dp[t_{i-1}][y],y\in[x-\Delta t,x+\Delta t]\} \]

然后我们需要敏锐地观察力和经验发现,对于固定的\(t_i\)\((x,dp_{t,x})\)构成了一个下凸函数

那么可以发现对于凸壳左半侧,\(dp_{t_i,x}=dp_{t_{i-1},x+\Delta t}\)

对于右半侧\(dp_{t_i,x}=dp_{t_{i+1},x-\Delta t}\)

等于将左半侧凸壳向右移动\(\Delta t\),右半侧凸壳向左移动\(\Delta t\)

第二部分\(F(t,x)\),以向左发射为例,对于小于\(x_i\)的部分是一个斜率为\(-1\)的一次函数,对于大于\(x_i\)的部分是贡献为\(0\)的常函数

现在介绍维护凸壳,每次只会对凸壳某一部分的斜率改变一个单位,且相邻两部分之间斜率相差\(1\),因为只要维护凸壳的断点在哪里

将左侧和右侧分开维护,并手动统计斜率为\(0\)的部分的答案

后面细节看上面博客

原文地址:https://www.cnblogs.com/knife-rose/p/15746153.html