[NOIP2008 提高组] 传纸条
算法
初步分析
对于一个点从 \((1, 1)\) 到 \((m, n)\) , 显然是好求的
但是本题中出现了两个路径, 朴素的想法是 :
先跑一遍从左上到右下的最大贡献, 标记已经跑过的点, 再从右下到左上时排除这些点
但是正确性如何呢?
显然是错误的, 观察到对于某些图, 贪心的求可能会将某些不是最大但是较大的数封闭起来, 使总的贡献不是最优, 例如这样一组数据
0 1 1
1 1 1
5 7 1
5 5 1
左下角的 \(5\) 就会被放弃, 使得总的贡献不是最优
综上所述, 我们必须综合考虑两条路径, 才能达到最优情况
正解
观察到两条路径起点和终点都为 \((1, 1)\) 和 \((m, n)\)
考虑将第二条路径翻转, 问题转化为
两路径, 从 \((1, 1)\) 开始到 \((m, n)\) 结束, 路径经过的点不重复, 求点的最大贡献和
容易想到令 \(dp_{x_1, y_1, x_2, y_2}\) 表示两条路径到达分别为 \((x_1, y_1)\) 和 \((x_2, y_2)\) 两点时, 最大的贡献和
则有
\[dp_{x_1, y_1, x_2, y_2} = \max{\left(dp_{x_1 - 1, y_1, x_2 - 1, y_2}, dp_{x_1, y_1 - 1, x_2 - 1, y_2}, dp_{x_1 - 1, y_1, x_2, y_2 - 1}, dp_{x_1, y_1 - 1, x_2, y_2 - 1} \right)} + Val_{x_1, y_1} + Val_{x_2, y_2}
\]
当 \((x_1, y_1)\) 和 \((x_2, y_2)\) 重合时, 注意判定使一条路径的贡献 \(= 0\) , 这样在 \(\rm{dp}\) 中显然不会优, 会被更新抹除
优化 1
观察到 \(x_1 + y_1, x_2 + y_2\) 恒为定值
用 \(k = x_1 + y_1\) 可优化掉一维
此时的状态转移方程 :
\[dp_{k, x_1, x_2} = \max{\left(dp_{k - 1, x_1 - 1, x_2 - 1}, dp_{k - 1, x_1, x_2 - 1}, dp_{k - 1, x_1 - 1, x_2}, dp_{k - 1, x_1, x_2} \right)} + Val_{x_1, k - x_1} + Val_{x_2, k - x_2}
\]
重合判定如上
优化 2
\(k\) 可以滚动数组优化掉
代码
这里就不做细讲
for (i = 4; i < n + m; ++i)
{
/*注意要倒序枚举 j 和 k , 对于滚动数组的优化*/
for (j = min(i - 2, n); j >= 1; --j)
{
for (k = min(i - 1, n); k > j; --k)
{
if(j == k) ________;
else __________;
}
}
}
总结
双路径问题, 考虑一起放进转移方程中
本题中的转移注意限制不超出, 不重合
处理重合问题的一个 \(\rm{trick}\) : 将重合情况变得劣

浙公网安备 33010602011771号