合并石子(区间DP)
有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动相邻的2堆石子合并,合并花费为新合成的一堆石子的数量。求将这N堆石子合并成一堆的总花费最小。
区间DP思想:现在小区间进行DP得到最优解,然后再利用小区间的最优解组合并求大区间的最优解。(需要从小到大枚举所有可能的区间)
代码(没提交过,不过应该正确):
include
using namespace std;
const int maxn1=300;
int main()
{
int n,a[maxn1]={0},sum[maxn1]={0};
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],sum[i]=a[i]+sum[i-1]; //前缀和
int dp[maxn1][maxn1]={0}; //dp[i][j]表示区间[i,n]的最小花费
for(int len=1;len<n;len++) //枚举所有可能的区间
{
for(int i=1;i<=n-len;i++)
{
dp[i][i+len]=INT_MAX;
for(int k=i;k<i+len;k++)
dp[i][i+len]=min(dp[i][i+len],dp[i][k]+dp[k+1][i+len]+sum[i+len]-sum[i-1]);
}
}
cout<<dp[1][n]<<endl;
return 0;
}
这样写很容易理解,但复杂度为O(n^3),基本最多只能计算250堆石子。
在网上看了一个平行四边形对区间DP的优化,复杂度基本可以维持在O(n^2),但是我却始终不理解其原理,不过大概按葫芦画瓢,写了一个(并注释了与之前O(n^3)的不同):
include
using namespace std;
const int maxn1=3000;
int main()
{
int n,a[maxn1]={0},sum[maxn1]={0},s[maxn1][maxn1];
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],sum[i]=a[i]+sum[i-1];
for(int i=1;i<=n;i++) //多加
s[i][i]=i; //多加 (记录区间最优解的位置)
int dp[maxn1][maxn1]={0};
for(int len=1;len<n;len++)
{
for(int i=1;i<=n-len;i++)
{
dp[i][i+len]=INT_MAX;
for(int k=s[i-1][i+len];k<=s[i+1][i+len];k++) //改变
if(dp[i][k]+dp[k+1][i+len]+sum[i+len]-sum[i-1]<dp[i][i+len]) //改变
{
dp[i][i+len]=dp[i][k]+dp[k+1][i+len]+sum[i+len]-sum[i-1]; //改变
s[i][i+len]=k; //改变
}
}
}
cout<<dp[1][n]<<endl;
return 0;
}
合并石子(区间DP)的更多相关文章
- 洛谷P1880 石子合并(区间DP)(环形DP)
To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...
- 直线石子合并(区间DP)
石子合并 时间限制:1000 ms | 内存限制:65535 KB 描述有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费 ...
- CH5301 石子合并【区间dp】
5301 石子合并 0x50「动态规划」例题 描述 设有N堆沙子排成一排,其编号为1,2,3,…,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆, ...
- zjnu 1181 石子合并(区间DP)
Description 在操场上沿一直线排列着 n堆石子. 现要将石子有次序地合并成一堆.规定每次仅仅能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.同意在第一次合并前对调一 ...
- nyoj 737 石子合并(区间DP)
737-石子合并(一) 内存限制:64MB 时间限制:1000ms 特判: No通过数:28 提交数:35 难度:3 题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为 ...
- 石子合并2——区间DP【洛谷P1880题解】
[区间dp让人头痛……还是要多写些题目练手,抽空写篇博客总结一下] 这题区间dp入门题,理解区间dp或者练手都很妙 ——题目链接—— (或者直接看下面) 题面 在一个圆形操场的四周摆放N堆石子,现要将 ...
- 石子合并问题 /// 区间DP oj2025
Description 在一个圆形操场的四周摆放着n堆石子.现要将石子有次序地合并成一堆. 规定每次只能选相邻的两堆石子合并成新的一堆,并将新得的这堆石子数记为该次合并的得分. 试设计一个算法,计算出 ...
- 石子合并 (区间DP)
一.试题在一个园形操场的四周摆放N堆石子(N≤100),现要将石子有次序地合并成一堆.规定每次仅仅能选相邻的两堆合并成新的一堆,并将新的一堆的石子数.记为该次合并的得分.编一程序.由文件读入堆数N及每 ...
- 合并傻子//区间dp
P1062 合并傻子 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 从前有一堆傻子,钟某人要合并他们~但是,合并傻子是要掉RP的...... 描述 在一个园 ...
- nyoj 737 石子合并 经典区间 dp
石子合并(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆 ...
随机推荐
- 一个阿里云apache服务器配置两个或多个域名forLinux
一个阿里云apache服务器配置两个或多个域名for Linux: 默认已经配置好了阿里云提供的一键web安装,可以参考:http://www.42iot.com/?id=8 修改/alidata/s ...
- [常用类]时间内Date、SimpleDateFormat、Calendar类
Date类的概述是util包下的,不能导入sql包的.* 类 Date 表示特定的瞬间,精确到毫秒. *构造方法 * public Date() * public Date(long date) 如果 ...
- Dubbo一文入门
一.简介 系统的架构,已从最早的单体式架构(一个war包完事)逐渐发展到目前的微服务式架构.微服务,将一个大型的复杂的应用系统,拆分成若干独立的松耦合的小的服务工程,每个服务工程可独立部署,每个服务只 ...
- linux中的一些常用命令
shutdown -h now 现在马上关机 shutdown -r now 现在重新启动 reboot 现在重新启动 su - 如果当前是普通用户,则输入这条命令切换到管理员用户(root),如果要 ...
- Linux就该这么学04学习笔记
今天开始学习,开始做笔记,希望自己能坚持下去 参考链接:https://www.linuxprobe.com/chapter-04.html vim编辑器 Linux系统中通用的文本编辑器 vi的升级 ...
- 2019ICPC网赛南京站B题 super_log(欧拉降幂
https://nanti.jisuanke.com/t/41299 题意:让算a^(a^(a^(...))),一共b个a, (mod p)的结果. 思路:这是个幂塔函数,用欧拉降幂公式递归求解. # ...
- python struct中的pack unpack
python struct中的pack unpack pytyon tuple元组 print struct.unpack("!ihb", buffer) 结果为7 //pyth ...
- 占卜DIY
题目地址 Code #include<iostream> #include<vector> #include<map> using namespace std; s ...
- css3 :enabled与:disabled伪类选择器
css :enabled和:disabled伪类选择器 在Web表单中,有些表单元素(如输入框.密码框.复选框等)有“可用”和“不可用”这2种状态.默认情况下,这些表单元素都处在可用状态. 在CSS3 ...
- django之mysql数据库的配置和orm交互
一:django默认数据库的配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path. ...