区间动态规划 P1880 [NOI1995] 石子合并

#include<bits/stdc++.h>
#include <iostream>
using namespace std;


//区间动态规划

//P1880 [NOI1995] 石子合并

//fx[i][j]表示区间i到j的最大合并值

//推导:细分从一堆开始
//边界:f(i,i) = 0
//f(1,2) = f(1,1) +f(2,2)+ sum(1,2)  sum(1,2)表示从1到2的区间和
//每次区间石子的合并最后都要加上此区间的总和这个与石子的合并顺序无关


//环装开2倍数组
int m_max[205][205],m_min[205][205];//存最大最小值的数组
int sum[205];//前缀和
int a[205];//石子堆
int N;

int main()
{
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
    {
        scanf("%d",&a[i]);
        a[i+N]=a[i];//取相同的一段接到后面相当于环
        //初始化   f(i,i) = 0
        m_min[i][i]=0;
        m_max[i][i]=0;
    }
    //求前缀和
    sum[0]=0;
    for(int i=1;i<=2*N;i++)
    {
        sum[i]=sum[i-1]+a[i];
    }

    //动态规划
    //采用枚举区间长度的方法
    //因为区间长度为1的为0,边界:f(i,i) = 0,直接从2开始枚举
    for(int len=2;len<=N;len++)
    {
        for(int left=1;left+len-1<=2*N;left++)//区间的左端点
        {
            int right=left+len-1;//区间右端点
            m_min[left][right]=0x3f3f3f3f;//假设最小值很大
            m_max[left][right]=0;//假设最大值
            //分界线k
            for(int k=left;k<right;k++)//采用左闭右开    k+1<right
            {
                m_max[left][right]=max(m_max[left][right],m_max[left][k]+m_max[k+1][right]);
                m_min[left][right]=min(m_min[left][right],m_min[left][k]+m_min[k+1][right]);
            }
            //每次合并固定要不变要加上的部分区间left到right的石子总和
            m_max[left][right]+=sum[right]-sum[left-1];
            m_min[left][right]+=sum[right]-sum[left-1];

        }
    }
    //最后寻找长度为N的区间的最大最小值
    int mi=0x3f3f3f3f;
    int ma=-1;
    for(int i=1;i<=N;i++)
    {
        if(m_max[i][i+N-1]>ma) ma=m_max[i][i+N-1];
        if(m_min[i][i+N-1]<mi) mi=m_min[i][i+N-1];
    }
    printf("%d\n%d",mi,ma);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值