合并石子

来源:互联网 发布:女生长得丑自卑知乎 编辑:程序博客网 时间:2024/04/29 09:06

描述

在一个圆形操场的四周摆放着n 堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。

输入

在每组测试数据中。第1行是正整数n,表示有n堆石子。第2 行有n个数,分别表示每堆石子的个数。

输出

程序运行结束时,将计算结果输出。第1 行中的数是最小得分;第2 行中的数是最大得分。

样例输入

4
4 4 5 9

样例输出

43
54

#include <iostream>#include <stdio.h>#include <string.h>#include <string>#include <limits.h>using namespace std;int dpx[1100][110],p[1100][1100],s[1100],dp[1100][1100];int anx,any;int main(){   int n;   while(cin>>n)   {       memset(p,0,sizeof(p));       for(int i=1;i<=n;i++)       {           cin>>s[i];           s[n+i]=s[i];       }       for(int i=1;i<=2*n;i++)        {            p[i][i]=s[i];            for(int j=i+1;j<=2*n;j++)                p[i][j]=p[i][j-1]+s[j];        }       memset(dp,0,sizeof(dp));       for(int r=1;r<n;r++)       {           for(int i=1;i<=2*n-r;i++)           {               int j=r+i;               dpx[i][j]=INT_MAX;               for(int k=i;k<j;k++)               {                   dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+p[i][j]);                   dpx[i][j]=min(dpx[i][j],dpx[i][k]+dpx[k+1][j]+p[i][j]);               }           }       }       anx=0;       any=INT_MAX;       for(int i=1;i<=n;i++)       {          anx=max(anx,dp[i][n+i-1]);          any=min(any,dpx[i][n+i-1]);       }       printf("%d\n",any);       printf("%d\n",anx);   }   return 0;}


0 0
原创粉丝点击