CF2049D 题解

CF2049D 题解

题意

给定一个 n×m 的数字矩阵和常数 K,初始位于 (1,1) 点,只能通过向下或者向右走来到达 (n,m) 点。

存在某种操作,可以选择任意一行 ,将其所有列元素逆时针旋转 1 个单位,这个操作可以对任意行进行任意次(下面称这个操作为“旋转”)。

设最后总操作次数为 x,经过的所有元素和为 S,最后的代价就是 K×x+S,求出这个代价可能的最小值。

注意:所有“旋转”操作需要在出发之前确定,或者等效来讲,不可以在某一行上移动时,对该行进行“旋转”操作。

分析

这个问题很明显可以 DP,并且有两个显然的观察:

  1. 每一行的旋转与否、旋转的次数是彼此之间独立的。
  2. 任意一行的旋转次数不会超过 m1 次,否则就是无用功。

那么就可以很自然的得到 DP 的定义:dp[i][j][k],k[0,m1] 为 到达 (i,j) 点,当前行旋转了 k 次的最小代价。

那么对于某个点 (i,j),其只会从 (i1,j)(i,j1) 转移。

(i1,j) 转移的时候,完全可以不用关心 i1 行旋转了多少次,正如上文 “1” 所说,行与行之间的旋转操作是独立的,我只需要知道到达 (i1,j) 这个点的最小代价即可,这一过程可以通过在 DP 过程中随手记录下最小值实现。

(i,j1) 转移的时候,dp[i][j][k] 仅可从 dp[i][j1][k] 转移,这一点在 “注意” 中已经指出。

那么这样一来整个流程就明了了,唯一需要再额外注意的地方在于可能会有数据溢出的情况。

Code

posted @   Hanggoash  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
动态线条
动态线条end
点击右上角即可分享
微信分享提示