石子合并(NOI1995)

时间限制: 1 Sec  内存限制: 128 MB
提交: 90  解决:
48
[提交][状态][讨论版]

题目描述

在操场上沿一直线排列着
n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆石子合并成新的一堆,
并将新的一堆石子数记为该次合并的得分。允许在第一次合并前对调一次相邻两堆石子的次序。 
计算在上述条件下将n堆石子合并成一堆的最小得分和初次交换的位置。

输入

输入数据共有二行,其中,第1行是石子堆数n≤100; 
第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔。

输出

输出合并的最小得分。

样例输入

3
2 5 1

样例输出

11

看题目可以看出它是没有环的,貌似有环的石子归并也有。题目中开始可以交换相邻的两堆石子可以用枚举实现,然后就是2D/1D类型的dp
一次复杂度为O(n^3),所有总复杂度为O(n^4),这是复杂度一算为1*10^8,也就是100 million,这个还需要卡常数,在当时绝对是卡不过去的,
这时一个非常强势的优化就出现了,那就是平行四边形优化,可以缩掉一维转移的时间。

【定理 1】假如函数 w 满足上述条件,那么函数 m 也满足四边形不等式,即

m (i, j ) + m (i’, j') £ m (i', j ) + m (i , j')  i ≤ i' < j ≤ j'

我们定义 s (i , j ) 为函数 m (i , j ) 对应的决策变量的最大值

【定理 2】假如 m (i , j ) 满足四边形不等式,那么 s (i , j ) 单调,即:

s (i, j ) ≤ s (i, j +1) ≤ s (i + 1, j +1)

以上比较粗略,详细可以见

动态规划加速原理之四边形不等式 华中师大一附中 赵爽

看一下代码比较好

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<iostream> using namespace std;
const int MAXN=;
int n,ans,dp[MAXN][MAXN],a[MAXN],s[MAXN][MAXN],sum[MAXN]; void solve()
{
memset(dp,,sizeof(dp));
memset(s,,sizeof(s));
for (int i=;i<=n;i++)
{
sum[i]=a[i]+sum[i-];
dp[i][i]=;
s[i][i]=i;
}
for (int t=;t<n;t++)
for (int i=;i<=n-t;i++)
{
int j=i+t;
dp[i][j]=MAXN*MAXN*MAXN;
for (int k=s[i][j-];k<=s[i+][j];k++) //这里s即为平行四边形优化的数组
{
if (dp[i][j]>dp[i][k]+dp[k+][j]+sum[j]-sum[i-])
{
dp[i][j]=dp[i][k]+dp[k+][j]+sum[j]-sum[i-];
s[i][j]=k; //记录下i,j的最优转移点。
}
}
}
ans=min(ans,dp[][n]);
}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
ans=MAXN*MAXN*MAXN;
solve();
for (int i=;i<n;i++)
{
swap(a[i],a[i+]);
solve();
swap(a[i],a[i+]);
}
cout<<ans<<endl;
}

石子合并(NOI1995)的更多相关文章

  1. P1880 [NOI1995]石子合并[区间dp+四边形不等式优化]

    P1880 [NOI1995]石子合并 丢个地址就跑(关于四边形不等式复杂度是n方的证明) 嗯所以这题利用决策的单调性来减少k断点的枚举次数.具体看lyd书.这部分很生疏,但是我还是选择先不管了. # ...

  2. [NOI1995]石子合并 题解

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

  3. 洛谷 P1880 [NOI1995]石子合并 题解

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

  4. 区间DP小结 及例题分析:P1880 [NOI1995]石子合并,P1063 能量项链

    区间类动态规划 一.基本概念 区间类动态规划是线性动态规划的拓展,它在分阶段划分问题时,与阶段中元素出现的顺序和由前一阶段的那些元素合并而来由很大的关系.例如状态f [ i ][ j ],它表示以已合 ...

  5. P1880 [NOI1995]石子合并 区间dp

    P1880 [NOI1995]石子合并 #include <bits/stdc++.h> using namespace std; ; const int inf = 0x3f3f3f3f ...

  6. 【区间dp】- P1880 [NOI1995] 石子合并

    记录一下第一道ac的区间dp 题目:P1880 [NOI1995] 石子合并 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码: #include <iostream> ...

  7. [洛谷P1880][NOI1995]石子合并

    区间DP模板题 区间DP模板Code: ;len<=n;len++) { ;i<=*n-;i++) //区间左端点 { ; //区间右端点 for(int k=i;k<j;k++) ...

  8. 洛谷 P1880 [NOI1995] 石子合并(区间DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是石子合并问题稍微升级版 这道题和经典石子合并问题的不同在于,经典的石子合 ...

  9. NOI1995石子合并&多种石子合并

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

随机推荐

  1. Maven生成可以直接运行的jar包的多种方式

    Maven可以使用mvn package指令对项目进行打包,如果使用Java -jar xxx.jar执行运行jar文件,会出现"no main manifest attribute, in ...

  2. cocos quick lua 输入框点击穿透的问题处理方案。

    条件:当前版本quick-3.3 -lua,系统 win7. 问题:在输入框(textField或者editbox,下文"输入框"就代表这两种)打开的情况下弹出其他界面盖住输入框, ...

  3. Apache Camel之FTP组件学习

    写在最前面 哎,最近提了离职,手头的活也基本上清理的差不多了.想着这个把月可以舒服的晃悠晃悠的离开,但是运维的小伙伴总是不架势,走之前还是提了个新需求. 先说下需求吧,我们的系统概括的讲就是一个接口系 ...

  4. Swiper 滑动

    1.http://www.swiper.com.cn/download/  下载Swiper.JS  Swiper.CSS 2.引入项目,添加html <div class="cont ...

  5. C# 委托、匿名方法、lambda简介

    在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个First不 ...

  6. Apache配置虚拟域名

    在作php本地调试的时候,一般都要打上localhost/,如果你的项目层级关系比较多,那你的url地址就会很长. 那我们能不能用一个简短的域名去替代那些一长串无用的字符呢? 那可能有人会问如果我没有 ...

  7. mysql中int(10)与int(11)有什么区别吗?

    先来看下面的图片 声明字段是int类型的那一刻起,int就是占四个字节,一个字节8位,也就是4*8=32,可以表示的数字个数是2的32次方(2^32 = 4 294 967 296个数字). 4 29 ...

  8. 201521123011《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. XMind 2. 书面作业 1.clone方法 1.1 O ...

  9. 201521123047 《Java程序设计》第4周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 答: - 只能有一个父类,即单继承,子类继承父类的全部成员(属性和方法),并可能有自己特有的 ...

  10. java第二次实验

    1. 本章学习总结 答:学会在java中使用函数调用. 学会在Java程序中使用函数,使程序层次更清晰. 使用StringBuilder代替string拼接,减少内存空间的占用. 使用BigDecim ...