P1005 [NOIP2007 提高组] 矩阵取数游戏

思维题:

显然每个行可以互相独立来处理。

贪心和暴力显然都不容易处理这题,所以我们只能考虑dp。

每次只能取最左边和最右边的数,这显然很符合区间dp的特点。

所以我们令dp[i][j]为取[i,j]区间所能获得的最大值

最后的答案便是dp[1][len]的累和

现在想dp[1][len]该如何获得呢?

显然dp[1][len]只能从dp[2][len]或dp[1][len-1]中得到。

但是每次取的是最左边或最右边的数,显然我们是不知道dp[2][len]和dp[1][len-1]的值的

所以这道题要逆这来思考过程。

一开始我们从这序列中任意取一个元素,此时便是dp[i][i]=a[i]

然后显然只能从 i-1或 i+1来取数,这样区间长度为2的dp状态我们也处理好了

接着便是长度为3,4......,len的长度取完

所以对于dp[i][j]的转移方程便是dp[i][j]=max(dp[i+1][j]*2+a[i],dp[i][j-1]*2+a[j])

这道题要求高精度,所以直接python来写就好了

Code:

复制代码
N=100
dp=[ [ [0]*N for j in range(N) ] for i in range(N)]
a=[ [0] for i in range(N)]


n,m=map(int,input().split())
for i in range(1,n+1):
    a[i]=a[i]+list(map(int,input().split()))

for i in range(1,n+1):
    for j in range(1,m+1):
        dp[i][j][j]=a[i][j]

for line in range(1,n+1):
    for len in range(2,m+1):
        for i in range(1,m+1):
            j=i+len-1
            if(j>m):
                break
            dp[line][i][j]=max(dp[line][i+1][j]*2+a[line][i],dp[line][i][j-1]*2+a[line][j])
ans=0
for i in range(1,n+1):
    ans+=dp[i][1][m]*2
print(ans)
复制代码

 

posted @   QAQ啥也不会  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示