NC16645 矩阵取数游戏(记忆化搜索)

题目链接

题意:
有 n 行 m 列 的 矩 阵 有n行m列的矩阵 nm
对 于 第 i 行 , 可 以 取 出 行 首 或 行 尾 的 一 个 元 素 对于第i行,可以取出行首或行尾的一个元素 i
对 于 每 一 行 第 k 次 取 出 可 以 得 到 2 k ∗ a i j 的 分 数 对于每一行第k次取出可以得到 2^k *a_{ij}的分数 k2kaij
问 最 多 能 得 到 多 少 分 问最多能得到多少分
题解:
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]ij
每 一 行 有 m 个 元 素 , 所 以 可 以 计 算 出 当 前 已 经 取 元 素 的 次 数 每一行有m个元素,所以可以计算出当前已经取元素的次数 m
m − r + l 就 是 取 元 素 的 次 数 , 可 以 用 来 计 算 2 k m -r+l就是取元素的次数,可以用来计算2^k mr+l2k
然 后 列 出 转 移 方 程 式 然后列出转移方程式
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]ai2k+f[i][r1]ar2k
边 界 就 是 i = = j 的 时 候 , 说 明 这 是 最 后 一 个 元 素 边界就是i==j的时候,说明这是最后一个元素 i==j
就 可 以 直 接 返 回 a i ∗ 2 m 就可以直接返回a_i*2^m ai2m
但 是 需 要 注 意 的 是 , 这 个 数 据 是 会 爆 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)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值