环形石子合并

题目描述

在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。

试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.

输入输出格式

输入格式:

 

数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.

 

输出格式:

 

输出共2行,第1行为最小得分,第2行为最大得分.

 

输入输出样例

输入样例#1: 复制
4
4 5 9 4
输出样例#1: 复制
43
54
算法:动态规划
#include<iostream>  
#include<cstdio>
#include<limits.h>
#include<cstring> 
#include<algorithm>
using namespace std;   
const int N=310;
int n,mil,mxl,f1[N][N],f2[N][N],a[N];  
int s[N];  

int main()  
{   
    cin>>n;
    memset(f1,0x3f,sizeof(f1));
    for(int i=1;i<=n+n;i++)  
    {  
        cin>>a[i];  
        a[i+n]=a[i];
        s[i]=s[i-1]+a[i];
        f1[i][i]=0;
    }  
    for(int i=2;i<=n;i++)  
    {  
        for(int j=1;j<=2*n-i+1;j++){
            int l=j,r=j+i-1;
            for(int k=l;k<r;k++){
                f1[l][r]=min(f1[l][r],f1[l][k]+f1[k+1][r]+s[r]-s[l-1]);
                f2[l][r]=max(f2[l][r],f2[l][k]+f2[k+1][r]+s[r]-s[l-1]);
            }
                
        }
    }  
    mil=INT_MAX;  
    for(int i=1;i<=n;i++)  
    {  
        mxl=max(mxl,f2[i][i+n-1]);  
        mil=min(mil,f1[i][i+n-1]);  
    }  
    cout<<mil<<endl;
    cout<<mxl;
    return 0;  
}

 

posted @ 2019-07-23 22:27  YF-1994  阅读(482)  评论(0编辑  收藏  举报