Loading

[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}\) : 将重合情况变得劣

posted @ 2024-11-12 14:20  Yorg  阅读(37)  评论(0)    收藏  举报