首页 > 其他 > 详细

区间DP——石子合并<一>(未完结)

时间:2019-07-30 15:53:07      阅读:67      评论:0      收藏:0      [点我收藏+]

A. 石子合并<一>

内存限制:128 MiB    时间限制:1000 ms    标准输入输出
题目类型:传统    评测方式:文本比较

题目描述

有N堆石子排成一排(n<=100),现要将石子有次序地合并成一堆,规定每次只能选相邻的两堆合并成一堆,并将新的一堆的石子数,记为改次合并的得分,编一程序,由文件读入堆数n及每堆石子数(<=200);

(1)选择一种合并石子的方案,使得做n-1次合并,得分的总和最少

(2)选择一种合并石子的方案,使得做n-1次合并,得分的总和最多

输入格式

第一行为石子堆数n 第二行为每堆石子数,每两个数之间用一空格分隔。

输出格式

从第1行为得分最小第二行是得分最大。

样例

样例输入
4
4 5 9 4


样例输出
44
54

 

思路

附上代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,dpmax[500][500],dpmin[500][500]/*前i-j最优解*/,sum[500][500],read[500],tot;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>read[i];
    }
    for(int i=1;i<=n;i++)
    {
        tot=read[i];
        for(int j=i+1;j<=n;j++)
        {
            tot+=read[j];
            sum[i][j]=tot;
        }
    }
    memset(dpmin,0x3f,sizeof(dpmin));
    for(int i=1;i<=n;i++)
        dpmin[i][i]=0; 
    for(int len=1;len<n;len++)
    {
        for(int i=1;i<=n&&len+1<=n;i++)
        {
            int j=len+i;
            for(int k=i;k<=j;k++)
            {
                dpmax[i][j]=max(dpmax[i][j],dpmax[i][k]+dpmax[k+1][j]);
                dpmin[i][j]=min(dpmin[i][j],dpmin[i][k]+dpmin[k+1][j]);
            }
            dpmax[i][j]+=sum[i][j];
            dpmin[i][j]+=sum[i][j]; 
        }
    }
    cout<<dpmin[1][n]<<endl;
    cout<<dpmax[1][n];
}

 

区间DP——石子合并<一>(未完结)

原文:https://www.cnblogs.com/lihaolin/p/11270310.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!