矩阵取数游戏(区间dp+ 21 行 python 水高精)

矩阵取数游戏

题目描述

帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的 n×m 的矩阵,矩阵中的每个元素 a i,j均为非负整数。游戏规则如下:
每次取数时须从每行各取走一个元素,共 n 个。经过 m 次后取完矩阵内所有元素;
每次取走的各个元素只能是该元素所在行的行首或行尾;
每次取数都有一个得分值,为每行取数的得分之和.帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。

题目思路

看到数据范围为80可知,这题能用n3的解法完成,n3考虑区间dp.
已知要求取数后的最大得分,即sum1 + sum2 + sum3 + … + sum3
而sum又等于(令第i行在第j次的值是mij)m1j + m2j + m3j + m4j + … + mnj
即总数可化简(m11 + m12 + m13 … + m1m) + (m21 + m22 …) + (…)
.其实化简到这里题目就很简单了,就是每一行的最大值之和.对每一行使用区间dp即可求出最后答案.由于最后答案会爆long long,所以可以用__int128(但是博主比较懒,直接用python了)

maxn = 87
dp = [[[-1 for i in range(maxn)] for j in range(maxn)] for k in range(maxn)]
arr = []

def dfs(now, l, r, i):
    if dp[now][l][r] != -1 :
        return int(dp[now][l][r])
    if l == r:
        dp[now][l][r] = pow(2, i) * arr[now][l]
        return int(dp[now][l][r])

    dp[now][l][r] = max(dp[now][l][r], dfs(now, l, r - 1, i + 1) + (arr[now][r] * pow(2, i)), dfs(now, l + 1, r, i + 1) + (arr[now][l] * pow(2, i)))
    return int(dp[now][l][r])

if __name__ == "__main__":

    n, m = map(int, input().split())

    for i in range(n):
        arr.append(list(map(int, input().split())))

    ans = 0
    for i in range(n):
        ans += dfs(i, 0, m - 1, 1)
    print(ans)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值