1563.石子游戏V
题目分析 本题首先规定了游戏规则如下: 将当前余下的石头分成左右非空的两部分; 分别计算两部分的石头价值总和,若两者不等,则保留总和较小的一部分,否则任选一部分保留; 将留下的石子价值总和计入$Alice$的得分; 按照上述规则一直进行游戏,直到只剩下一个石子为止。求$Alice$的最大得分。 基本思路 如果进行了一次分割,那么无论最终留下哪一部分,其实问题都变成了一个规模更小但相似的子问题,故可以想到用动态规划进行解决,定义动态规划数组$dp$,其中$dp[i][j]$表示在区间$[i,j)$中$Alice$能够取得的最大得分,那么将$k$在$(i,j)$中遍历,则$dp[i][j]$的计算需要分以下两种情况: 为方便叙述,记$stoneValues[i:k]$的总和为$left$,$stoneValues[k:j]$的总和为$right$。 $$ dp[i][j] = max \begin{cases} dp[i][k]+left &,left\leq right\\ dp[k][j]+right &,left\geq right \end{cases} $$不难发现,由于$stoneValues$中的所有值都是正数,那么随着$k$的增加,$left$必定越来越大,$right$必定越来越小,故一定存在下标$p$,使得当$k\in (i,p]$时均满足$left\leq right$,同理,一定存在下标$q$,使得当$k \in [q,j)$时均满足$left \geq right$,可以发现,当存在一个$k$使得$left=right$时,$q=p$,否则,$q=p+1$。 因此,如果用前缀和数组$s$表示出$left$和$right$,并结合上述分析即可得到: $$ dp[i][j] = max \begin{cases} \max\limits_{k=i+1}^{p}(dp[i][k]+s[k]-s[i])\\ \max\limits_{k=q}^{j-1}(dp[k][j]+s[j]-s[k]) \end{cases} $$将与$k$无关的项提取出来即可得到: $$ dp[i][j] = max \begin{cases} -s[i]+\max\limits_{k=i+1}^{p}(dp[i][k]+s[k])\\ s[j]+\max\limits_{k=q}^{j-1}(dp[k][j]-s[k]) \end{cases} $$可以发现,后面求最大值的项中,$k$都是在区间$[i,j]$的前缀或后缀中遍历的,故如果能维护一个特定区间中指定式子的前缀最大值和后缀最大值,就可以快速求出$dp[i][j]$的值,定义前缀最大值数组$preMax[i][j]$表示$\max\limits_{k=i+1}^{j}(dp[i][k]+s[k])$,同时定义后缀最大值数组$sufMax[i][j]$表示$\max\limits_{k=i}^{j-1}(dp[k][j]-s[k])$,那么上面的递推关系式就变成了: $$ dp[i][j] = max \begin{cases} -s[i]+preMax[i][p]\\ s[j]+sufMax[q][j] \end{cases} $$同时根据定义可以得知$preMax$和$sufMax$数组的递推关系如下: $$ \begin{align} preMax[i][j] = max(preMax[i][j-1], dp[i][j]+s[j])\\ sufMax[i][j] = max(sufMax[i+1][j], dp[i][j]-s[i]) \end{align} $$有了递推关系式,接下来就需要确定区间左右端点遍历的顺序,注意到,在计算$preMax$的值时,位置$(i,j)$是由位置$(i,j-1)$转移过来的,说明$j$的遍历应当从前往后遍历,同时在计算$sufMax$的值时,位置$(i,j)$是由位置$(i+1,j)$转移过来的,说明$i$的遍历应当从后往前遍历。不过需要注意的是,并不是两个数组中的值都需要在$dp[i][j]$计算完毕后才更新,因为在计算$dp[i][j]$时,实际上需要用到一个$preMax[i][p]$,而$p$是在$i$之后的,故应当在向后计算$p$的位置时同步更新$preMax$中的值。 最后在$dp$中所有值计算完毕后,返回$dp[0][n]$即为答案。 实现细节 如果对于每一个区间都用遍历去寻找$p$和$q$的位置,时间复杂度则会到达$O(n^3)$,故需要将其简化,注意到当确定区间左端点$i$之后,由于$j$的遍历顺序是从前往后,因此$p$和$q$的位置一定是不断右移的,故对于每一个固定$i$的循环,都可以初始化一个$p$的位置,随着$j$的增加,每次都用while循环增加$p$直到满足要求,这样,对于每一个不同的$i$,$p$最多也就循环$n$次,而非暴力的$n^2$次,复杂度即可降为$O(n^2)$。 ...