MAXN = 1005 f = [[9999999999] * MAXN for i inrange(MAXN)] n = int(input()) m = list(map(int,input().split())) m.insert(0,0) # 算代价 s = [0] * (n + 10) for i inrange(1,n+1): s[i] = s[i-1] + m[i] defsum(l,r): return s[r] - s[l-1]
for i inrange(1,n+1): f[i][i] = 0 for length inrange(1,n+1): for l inrange(1,n-length+2): r = l + length - 1 for mid inrange(l,r): f[l][r] = min(f[l][r],sum(l,r) + f[l][mid] + f[mid + 1][r]) print(f[1][n])
标准版(考虑环)
上面是这个题目的弱化版的代码,接下来我们考虑如何将这个区间变成环,一个很简单的做法 (但是不好想) 就是我们将原始的石子复制两遍让他们首尾相接,之后正常转移,最后在 1~2n 的区间中寻找长度为 n 的石子最优解就可以了。
MAXN = 1005 f = [[9999999999] * MAXN for i inrange(MAXN)] g = [[0] * MAXN for i inrange(MAXN)] n = int(input()) a = list(map(int,input().split())) # 算代价 for i inrange(n): a.append(a[i]) a.insert(0,0) s = [0] * (2 * n+ 10) for i inrange(1,2 * n+1): s[i] = s[i-1] + a[i] defsum(l,r): return s[r] - s[l-1]
for i inrange(1,2 * n+1): f[i][i] = 0 g[i][i] = 0 for length inrange(1,n+1): for l inrange(1,2 * n-length+2): r = l + length - 1 for mid inrange(l,r): f[l][r] = min(f[l][r],sum(l,r) + f[l][mid] + f[mid + 1][r]) g[l][r] = max(g[l][r], sum(l, r) + g[l][mid] + g[mid + 1][r]) min_ans = 999999 max_ans = 0 for i inrange(0, n+1): min_ans = min(min_ans, f[1+i][n+i]) max_ans = max(max_ans, g[1+i][n+i]) print(str(min_ans) + "\n" + str(max_ans))