P1880 石子合并

题目描述

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

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例


这是一道区间dp十分经典的模板题,让我们揣测一下,前辈们是如何得到这个状态转移方程的。
首先,要计算合并的最大值、最小值,既然是动态规划,我们需要洞悉其中一些关联且确定的状态。
以下以最大值为例。
既然是最大值,那么求得的结果是否满足每一区间都是该区间所能达得到的的最大值?
显然是这样的。反证法:倘若有一个区间不是,那么换做该区间取得最大值的方案,最终结果将比原得分大。显然必定满足任意区间得分一定是该区间内的最大值。
这样我们可以定义状态f[i][j],表示i到j合并后的最大得分。其中1<=i<=j<=N。
既然这样,我们就需要将这一圈石子分割。很显然,我们需要枚举一个k,来作为这一圈石子的分割线。
这样我们就能得到状态转移方程:
f[i][j] = max(f[i][k] + f[k+1][j] + d(i,j));其中,1<=i<=<=k<j<=N。
d(i,j)表示从i到j石子个数的和。
那么如何编写更快的递推来解决这个问题?
在考虑如何递推时,通常考虑如下几个方面:
是否能覆盖全部状态?
求解后面状态时是否保证前面状态已经确定?
是否修改了已经确定的状态?
也就是说,在考虑递推顺序时,务必参考动态规划的适应对象多具有的性质,具体参考《算法导论》相关或百度百科或wiki。
既然之前说过我们需要枚举k来划分i和j,那么如果通过枚举i和j进行状态转移,很显然某些k值时并不能保证已经确定过所需状态。
如,i=1 to 10,j=1 to 10,k=1 to 9.当i=1,j=5,k=3时,显然状态f[k+1][j]没有结果。
那么,我们是不是应该考虑枚举k?
但这样i和j就难以确定了。
我们不难得到一个两全的方法:枚举j-i,并在j-i中枚举k。这样,就能保证地推的正确。

上代码。
#include<iostream>
#include<cstdio>
#include<cmath> using namespace std; int n,minl,maxl,f1[300][300],f2[300][300],num[300];
int s[300];
inline int d(int i,int j){return s[j]-s[i-1];}
//转移方程:f[i][j] = max(f[i][k]+f[k+1][j]+d[i][j]; int main()
{
scanf("%d",&n);
for(int i=1;i<=n+n;i++)
{
scanf("%d",&num[i]);
num[i+n]=num[i];
s[i]=s[i-1]+num[i];
}
for(int p=1;p<n;p++)
{
for(int i=1,j=i+p;(j<n+n) && (i<n+n);i++,j=i+p)
{
f2[i][j]=999999999;
for(int k=i;k<j;k++)
{
f1[i][j] = max(f1[i][j], f1[i][k]+f1[k+1][j]+d(i,j));
f2[i][j] = min(f2[i][j], f2[i][k]+f2[k+1][j]+d(i,j));
}
}
}
minl=999999999;
for(int i=1;i<=n;i++)
{
maxl=max(maxl,f1[i][i+n-1]);
minl=min(minl,f2[i][i+n-1]);
}
printf("%d\n%d",minl,maxl);
return 0;
}

边界状态还望读者仔细思考(不懂请留言)



放寒假了,是时候刷一波dp过过瘾了。


【洛谷】P1880 石子合并的更多相关文章

  1. 洛谷P1880 石子合并(区间DP)(环形DP)

    To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...

  2. 经典DP 洛谷p1880 石子合并

    https://www.luogu.org/problemnew/show/P1880 题目 题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新 ...

  3. 洛谷P1880 石子合并(环形石子合并 区间DP)

    题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...

  4. 洛谷 P1880 石子合并

    题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...

  5. 洛谷P1880 石子合并

    经典水题....... 断环为链长度乘二,求前缀和区间DP. #include <cstdio> #include <cstring> #include <algorit ...

  6. [codevs1048]石子归并&[codevs2102][洛谷P1880]石子归并加强版

    codevs1048: 题目大意:有n堆石子排成一列,每次可合并相邻两堆,代价为两堆的重量之和,求把他们合并成一堆的最小代价. 解题思路:经典区间dp.设$f[i][j]$表示合并i~j的石子需要的最 ...

  7. 洛谷 P1080 石子合并 ( 区间DP )

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

  8. 洛谷P1880 [NOI1995]石子合并 纪中21日c组T4 2119. 【2016-12-30普及组模拟】环状石子归并

    洛谷P1880 石子合并 纪中2119. 环状石子归并 洛谷传送门 题目描述1 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石 ...

  9. P1880 石子合并

    P1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计 ...

随机推荐

  1. CSS动画之transition属性

    transition 属性 简介 transition(过渡)) 是指从一个状态到另一个状态的变化.比如当鼠标在某个元素上悬停时,我们会修改它的样式,采用 transition 可以创建一个平滑的动画 ...

  2. vue实现分环境打包步骤(给不同的环境配置相对应的打包命令)

    在新建好的项目中,一般执行npm run build就是打包了,但此时只能打包到一个环境,不同环境需要配置不同的地址,可以手动更改接口的地址,也可以自行配置命令而不需要每次打包进行地址切换,步骤如下: ...

  3. python3快速安装

    linux环境快速安装python3   之前在linux上安装python3的时候,为了让不影响linux环境原有的python2的环境,选择的方法都是下载对应的linux环境的python包,不过 ...

  4. C语言实现 计算个人所得税务2种方法

    #include <stdio.h> #include <stdlib.h> /* 基于C语言的个人所得税计税系统 问题描述: 我国现行的个人所得税计算方法如下: 级数 全月应 ...

  5. Axure教程:如何使用动态面板?动态面板功能详解

    写了几个Axure教程之后发现,可能教程的起点有些高了,过分的去讲效果的实现,而忽略了axure功能以及基础元件的使用,那么从这个教程开始,把这些逐渐的展开讲解. 关于Axure动态面板 动态面板是a ...

  6. GitHub:如何构建一个股票市场知识图谱?(附代码&链接)

    来源:专知 本文约 600007 董事⻓/董事 高燕 女 60 600007 执⾏董事 刘永政 男 50 600008 董事⻓/董事 ··· ··· ··· ··· ··· 注:建议表头最好用相应的英 ...

  7. 在Jsp中调用静态资源,路径配置问题

    在Jsp中调用图片.JS脚本等,针对取得的路径有两种调用方式: 1.放入Body中生成绝对路径(不建议) <%@ page language="java" import=&q ...

  8. MFC安装与部署(程序打包)

    (发现csdn传照片实在是太麻烦, 不能够直接拖拽进来;所以我直接使用云笔记生成一张图片 直接完成!) (懒癌晚期-)

  9. python 创建txt每行写入

    txtPath=os.path.join(vocDir,"eval.txt") with open(txtPath,"w") as f: f.writeline ...

  10. sql 2000 or sql2005 数据库日志删除

    数据库日志清理(sql 2000 or sql2005)DUMP TRANSACTION crm WITH NO_LOGBACKUP LOG crm WITH NO_LOGDBCC SHRINKDAT ...