题目描述
魔法世界的魔法师曾经因臭氧层破坏而制造出覆盖整个星球大气层,用于抵御超量紫外线辐射的“天幕”。所以虽然太空防御系统是魔法世界历史上空前绝后的一项超大工程。但是具体实施起来并不是很困难,它其实是一个围绕整个星球赤道的圆形防御圈,圆形防御圈四周摆放N堆魔法石(N≤100),现要将魔法石有次序地合并成一堆。规定每次只能选相邻的两堆合并成一堆,并将新的一堆的魔法石数,记为该次合并的得分。编一程序,由文件读入堆数N及每堆魔法石数(≤20),使得:
(1)选择一种合并石子的方案,使得做N-1次合并,得分的总和最少;
(2) 选择一种合并石子的方案,使得做N-1次合并,得分的总和最大。
(1)选择一种合并石子的方案,使得做N-1次合并,得分的总和最少;
(2) 选择一种合并石子的方案,使得做N-1次合并,得分的总和最大。
输入
第一行为石子堆数N;
第二行为每堆石子数,每两个数之间用一空格分隔。
第二行为每堆石子数,每两个数之间用一空格分隔。
输出
两个数,即最大合并数和最小合并数。
样例输入
4
4 5 9 4
样例输出
54 43 【思】环形的区间DP。可以把原来长度为n的数组复制一下,变成2n。然后以区间长度从2到n开始dp。 dp[i][j]:代表从i开始连续长度为j的区间的最优解。 状态转移方程: dp[i][j]=wish{dp[i][k]+dp[i+k][j-k]}+w[i][j], (k:1..j-1.w[i][j]为从i开始连续长度为j的a[k]的和) 【code】#include using namespace std; const int INF = 2147483647; const int mx=205; int n,i,j,k,a[mx],d[mx][mx],f[mx][mx],Max,Min; int main() { scanf("%d",&n); for (i=1;i<=n;++i) { scanf("%d",&a[i]); a[i+n]=a[i]; } for (j=2;j<=n;++j) //length. { for (i=1;i<=n;++i) //start point. { Max=-INF; Min=INF; for (k=1;k