环形石子合并
题目描述
将n堆石子绕圆形操场排放,现要将石子有序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分。
请编写一个程序,进行如下计算:
选择一种合并石子的方案,使得做n-1次合并得分总和最小。
选择一种合并石子的方案,使得做n-1次合并得分总和最大。
输入描述
第一行包含整数n,表示共有n堆石子。1≤n≤200
第二行包含n个整数,分别表示每堆石子的数量。
输出描述
输出共两行:
第一行为合并得分总和最小值,
第二行为合并得分总和最大值。
样例输入
5
1 4 2 5 3
样例输出
34
47
代码详解
展开查看
n = int(input()) a = [0] for i in input().split(): a.append(int(i)) for i in range(1, n+1): a.append(a[i]) s = [0] f = [[1061109567 for j in range(201)] for i in range(201)] g = [[0 for j in range(310)] for i in range(310)] for i in range(1, 2*n+1): s.append(s[i-1] + a[i]) f[i][i] = 0 g[i][i] = 0 for len in range(2, n+1): for l in range(1, 2*n+1): r = l + len - 1 if r <= 2*n: for k in range(l, r): f[l][r] = min(f[l][r], f[l][k] + f[k+1][r] + s[r] - s[l - 1]) g[l][r] = max(g[l][r], g[l][k] + g[k+1][r] + s[r] - s[l - 1]) minv = 1061109567 maxv = 0 for i in range(1, n+1): minv = min(minv, f[i][i+n-1]) maxv = max(maxv, g[i][i+n-1]) print(minv) print(maxv)
运行结果
展开查看
5 1 4 2 5 3 34 47