题意:
有
n
行
m
列
的
矩
阵
有n行m列的矩阵
有n行m列的矩阵
对
于
第
i
行
,
可
以
取
出
行
首
或
行
尾
的
一
个
元
素
对于第i行,可以取出行首或行尾的一个元素
对于第i行,可以取出行首或行尾的一个元素
对
于
每
一
行
第
k
次
取
出
可
以
得
到
2
k
∗
a
i
j
的
分
数
对于每一行第k次取出可以得到 2^k *a_{ij}的分数
对于每一行第k次取出可以得到2k∗aij的分数
问
最
多
能
得
到
多
少
分
问最多能得到多少分
问最多能得到多少分
题解:
n
,
m
<
=
80
,
a
i
j
<
=
8000
n,m<=80,a_{ij}<=8000
n,m<=80,aij<=8000
可
以
发
现
,
每
一
行
是
独
立
的
,
所
以
对
每
一
行
进
行
单
独
分
析
可以发现,每一行是独立的,所以对每一行进行单独分析
可以发现,每一行是独立的,所以对每一行进行单独分析
使
用
记
忆
化
搜
索
,
f
[
i
]
[
j
]
表
示
取
走
i
到
j
两
边
的
元
素
,
最
多
能
得
到
的
分
使用记忆化搜索,f[i][j]表示取走i到j两边的元素,最多能得到的分
使用记忆化搜索,f[i][j]表示取走i到j两边的元素,最多能得到的分
每
一
行
有
m
个
元
素
,
所
以
可
以
计
算
出
当
前
已
经
取
元
素
的
次
数
每一行有m个元素,所以可以计算出当前已经取元素的次数
每一行有m个元素,所以可以计算出当前已经取元素的次数
m
−
r
+
l
就
是
取
元
素
的
次
数
,
可
以
用
来
计
算
2
k
m -r+l就是取元素的次数,可以用来计算2^k
m−r+l就是取元素的次数,可以用来计算2k
然
后
列
出
转
移
方
程
式
然后列出转移方程式
然后列出转移方程式
f
[
i
]
[
j
]
=
f
[
i
+
1
]
[
r
]
∗
a
i
∗
2
k
+
f
[
i
]
[
r
−
1
]
∗
a
r
∗
2
k
f[i][j]=f[i+1][r]*a_i*2^k+f[i][r-1]*a_r*2^k
f[i][j]=f[i+1][r]∗ai∗2k+f[i][r−1]∗ar∗2k
边
界
就
是
i
=
=
j
的
时
候
,
说
明
这
是
最
后
一
个
元
素
边界就是i==j的时候,说明这是最后一个元素
边界就是i==j的时候,说明这是最后一个元素
就
可
以
直
接
返
回
a
i
∗
2
m
就可以直接返回a_i*2^m
就可以直接返回ai∗2m
但
是
需
要
注
意
的
是
,
这
个
数
据
是
会
爆
l
o
n
g
l
o
n
g
的
但是需要注意的是,这个数据是会爆longlong的
但是需要注意的是,这个数据是会爆longlong的
所
以
我
直
接
用
的
p
y
t
h
o
n
所以我直接用的python
所以我直接用的python
AC代码
f = [[0 for i in range(100)] for i in range(100)]
n, m = map(int, input().split())
a = [0 for i in range(100)]
def dfs(l, r) :
len = r - l + 1
x = m - len + 1
if f[l][r] :
return f[l][r]
if l == r :
return a[l] * (2 ** x)
f[l][r] = max(dfs(l + 1, r) + a[l] * 2 ** x, dfs(l, r - 1) + a[r] * 2 ** x)
return f[l][r]
ans = 0
for i in range(n):
f = [[0 for i in range(100)] for i in range(100)]
a = list(map(int, input().split()))
ans += dfs(0, m - 1)
print(ans)