思维题:
显然每个行可以互相独立来处理。
贪心和暴力显然都不容易处理这题,所以我们只能考虑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)
标签:NOIP2007,P1005,len,取数,range,ans,line,dp From: https://www.cnblogs.com/Willette/p/17266431.html