Description
帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数。游戏规则如下:
1.每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素;
2.每次取走的各个元素只能是该元素所在行的行首或行尾;
3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值 * ,其中i表示第i次取数(从1开始编号);
4.游戏结束总得分为m次取数得分之和。
帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。
Solution
这种题目描述,包含了很多决策状态,肯定是动态规划来做的。由于每一行是独立的,不会相互影响,那么对每一行都取最优决策即可。
我们令 为当前行取[i,j]区间能得到的最优值,显然有递推式
显然有递推式,
对每行做上述dp,通过记忆化搜索保证每个状态只访问一次,这里需要使用高精度,跟zzugzx偷学了一手python
Code
while True:
try:
n, m = map(int, input().split());
dp = [[0 for i in range(81)] for i in range(81)];
a = [0 for i in range(n + 1)];
def solve(l, r):
p = r - l + 1;
k = m - p + 1;
if dp[l][r] :
return dp[l][r];
if l == r :
return a[l] * (2 ** k);
dp[l][r] = max(solve(l + 1, r) + a[l] * (2 ** k), solve(l, r - 1) + a[r] * (2 ** k));
return dp[l][r];
ans = 0;
for i in range(n):
dp = [[0 for i in range(100)] for i in range(100)];
a = list(map(int, input().split()));
ans += solve(0, m - 1);
print(ans);
except EOFError:
break 
京公网安备 11010502036488号