#qJDPybttg050106. 1574:矩阵取数游戏

1574:矩阵取数游戏

好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:


题目描述

原题来自:NOIP 2007

帅帅经常和同学玩一个矩阵取数游戏:对于给定的 n×mn \times m 的矩阵,矩阵中每个元素 aija_{ij} 均为非负整数。游戏规则如下:

  1. 每次取数时必须从每行各取走一个元素,共 nn 个,mm 次取完所有元素;
  2. 每次取走的各个元素只能是该元素所在行的行首或行尾;
  3. 每次取数都有一个分值,为每行取数得分之和,每行取数得分 == 被取走元素值 ×2i\times 2^i,其中 ii 表示第 ii 次取数,从 11 开始计数;
  4. 游戏结束时,总得分为 mm 次取数得分之和。

帅帅想让你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。


输入格式

输入包括 n+1n+1 行:

  • 第一行两个空格隔开的正整数 n,mn, m
  • 接下来 nn 行,每行 mm 个用空格隔开的整数,表示矩阵元素。

输出格式

输出为一个整数,为所输入矩阵取数后的最大得分。


样例

样例输入 1

2 3
1 2 3
3 4 2

样例输出 1

82

样例解释 1

矩阵为:

$$\begin{bmatrix} 1 & 2 & 3 \\ 3 & 4 & 2 \end{bmatrix}$$

游戏过程:

  1. 第一次取数(i=1i=1,乘 21=22^1=2):
    第一行取行首元素 11,得分 1×2=21 \times 2 = 2
    第二行取行尾元素 22,得分 2×2=42 \times 2 = 4
    第一次总得分 2+4=62+4=6
  2. 第二次取数(i=2i=2,乘 44):
    第一行剩余 [2,3][2,3],取行首 22,得分 2×4=82 \times 4 = 8
    第二行剩余 [3,4][3,4],取行首 33,得分 3×4=123 \times 4 = 12
    第二次总得分 8+12=208+12=20
  3. 第三次取数(i=3i=3,乘 88):
    第一行剩余 [3][3],取 33,得分 3×8=243 \times 8 = 24
    第二行剩余 [4][4],取 44,得分 4×8=324 \times 8 = 32
    第三次总得分 24+32=5624+32=56

总得分 6+20+56=826+20+56=82


数据范围

  • 对于 60%60\% 的数据,1n,m301 \le n, m \le 30,答案不超过 101610^{16}
  • 对于 100%100\% 的数据,1n,m801 \le n, m \le 800ai,j10000 \le a_{i,j} \le 1000

时空限制

  • 时间:1000 ms1000 \text{ ms}
  • 内存:524288 KB524288 \text{ KB}

提示
此问题可以 逐行独立求解,因为每行的取数顺序相互独立,只需对每一行求最大得分,然后加起来。

对于一行长度为 mm 的序列 a[1m]a[1 \dots m],每次取首或尾元素,第 ii 次取数权重为 2i2^i
可以转化为区间 DP:设 dp[l][r]dp[l][r] 表示剩余区间 [l,r][l, r] 时的最大得分。
当前取的是第 (m(rl+1)+1)(m - (r-l+1) + 1) 次,权重为 2m(rl+1)+12^{m-(r-l+1)+1}

状态转移:

$$dp[l][r] = \max \big( dp[l+1][r] + a[l] \times 2^{m-(r-l+1)+1},\ dp[l][r-1] + a[r] \times 2^{m-(r-l+1)+1} \big)$$

初始化 dp[i][i]=a[i]×2mdp[i][i] = a[i] \times 2^m(最后一次取)。

最终该行最大得分为 dp[1][m]dp[1][m]

由于 m80m \le 802802^{80} 非常大,必须使用高精度(如 Python 的大整数或 C++ 的高精度类)。

总复杂度 O(n×m2)O(n \times m^2),高精度运算会额外增加复杂度,但 n,m80n,m \le 80 可以接受。