【区间dp让人头痛……还是要多写些题目练手,抽空写篇博客总结一下】


这题区间dp入门题,理解区间dp或者练手都很妙

——题目链接——

(或者直接看下面)

题面

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

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

范围:1≤N≤100

分析

这个范围……感受到快乐了吗?

一般这种范围复杂度都超高哦~

这题是区间DP,我想看标题就知道了,如果没有学过区间DP的话……就先学吧(这个坑可能我得好久好久好久以后填)

这题四舍五入就是个模板(?)了

难点在于它是个环,不过处理起来难度也不大

我们把这个环破开复制一遍,那么它会成为一条链,就会便于 处理啦

在这个 2*n (复制过一遍)的数组上枚举 1~n 的区间就能得到这个环能组成的所有区间

然后就是区间DP的实现过程!(不懂试着看看代码,再不懂就找找博客 / 老师学一学)

转移方程式:

dpmax[j][ends]=max(dpmax[j][ends],dpmax[j][i]+dpmax[i+1][ends]+stone[ends]-stone[j-1]);
dpmin[j][ends]=min(dpmin[j][ends],dpmin[j][i]+dpmin[i+1][ends]+stone[ends]-stone[j-1]);

【 j 和 ends 是目前区间左右端点, i 是枚举的 j~ends 里的一点,用于断开区间更新dp数组】

【 stone 数组记录整段区间前缀和,便于统计数据; dpmax 和 dpmin 看名字估计也知道是干什么了吧】

放一张AC图(悄咪咪地)我知道我很菜鸡你们自己考虑看不看下面参考

代码参考

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,a[],stone[];
int dpmax[][];
int dpmin[][];
int main()
{
cin>>n;
for (int i=; i<=n; i++)
{
cin>>a[i];
}
memset(dpmax,-,sizeof(dpmax));
memset(dpmin,0x3f3f3f,sizeof(dpmin));
memset(stone,,sizeof(stone));
for (int i=; i<=n; i++)
{
stone[i]=stone[i-]+a[i];
dpmax[i][i]=;
dpmin[i][i]=;
}
for (int i=; i<=n; i++)
{
stone[i+n]=stone[i+n-]+a[i];
//stone记录前缀和,用前缀和处理比较轻松
dpmax[i+n][i+n]=;
dpmin[i+n][i+n]=;
}
//读入与初始化
for (int len=; len<=n; len++)
//len枚举区间长度
for (int j=; j+len<=*n; j++)
//j枚举区间左端点
{
int ends=j+len-;
//区间右端点
for (int i=j; i<ends; i++)
//枚举分割点
{
dpmax[j][ends]=max(dpmax[j][ends],dpmax[j][i]+dpmax[i+][ends]+stone[ends]-stone[j-]);
dpmin[j][ends]=min(dpmin[j][ends],dpmin[j][i]+dpmin[i+][ends]+stone[ends]-stone[j-]);
}
}//核心代码!!!状态转移
int ansmin=0x3f3f3f;
int ansmax=-;
for (int i=; i<=*n; i++)
{
ansmin=min(ansmin,dpmin[i][i+n-]);
//i+n-1刚好是每种区间,超级妙的思路
ansmax=max(ansmax,dpmax[i][i+n-]);
}
cout<<ansmin<<endl<<ansmax;
return ;
}
——撒花!!!!——

我是在网上找博客学的区间DP,大概是有部分参考

—>https://blog.csdn.net/qq_40772692/article/details/80183248

有问题欢迎大佬指正

到这里就结束了,感谢看完

ありがとうございます

石子合并2——区间DP【洛谷P1880题解】的更多相关文章

  1. 洛谷P1880题解

    题目 第一类区间DP模板题. 所谓第一类区间DP,是指合并型区间DP,状态转移方程一般形如 \(f_{i,j}=\max{f_{i,k}+f_{k+1,j}+cost_{i,j}}\) ,时间复杂度一 ...

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

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

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

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

  4. P1880 [NOI1995]石子合并【区间DP】

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

  5. 直线石子合并(区间DP)

    石子合并 时间限制:1000 ms  |  内存限制:65535 KB 描述有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费 ...

  6. CH5301 石子合并【区间dp】

    5301 石子合并 0x50「动态规划」例题 描述 设有N堆沙子排成一排,其编号为1,2,3,…,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆, ...

  7. zjnu 1181 石子合并(区间DP)

    Description 在操场上沿一直线排列着 n堆石子. 现要将石子有次序地合并成一堆.规定每次仅仅能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.同意在第一次合并前对调一 ...

  8. nyoj 737 石子合并(区间DP)

    737-石子合并(一) 内存限制:64MB 时间限制:1000ms 特判: No通过数:28 提交数:35 难度:3 题目描述:     有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为 ...

  9. nyoj 737 石子合并 经典区间 dp

    石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆 ...

随机推荐

  1. element-ui做表单验证 v-for遍历表单 自动生成校验规则 pc移动双适配

    整体思路: 1:利用element-ui的栅格实现小分辨率和大分辨率的适配 2:模拟一组数据,从中筛选出 绑定各个表单值的对象   以及生成验证规则对象 3:在script标签内 .data()外,自 ...

  2. hive-server 启动失败问题小记

    Unable to instantiate using constructor(MetricRegistry, HiveC onf) for reporter org.apache.hadoop.hi ...

  3. c 判断一个字符是否为字母

    #include <stdio.h> #include <wctype.h> int main () { ; wchar_t str[] = L"C++"; ...

  4. redis redis-cli

    默认无权限控制: 远程服务连接: $ redis-cli -h 127.0.0.1 -p 6379 windows下 :redis-cli.exe -h 127.0.0.1 -p 6379 redis ...

  5. nvm临时版本和永久版本

    nvm use 8.15.1//临时版本 nvm alias default 8.15.1//永久版本

  6. centos7 防火墙开启 (重点)

    如果在自己服务器上想开启远端访问功能,需要开启防火墙 1.通过systemctl status firewalld查看firewalld状态,发现当前是dead状态,即防火墙未开启. 2.通过syst ...

  7. vs下qt的信号与槽实现

    实现主窗口中Add按钮的功能, 这一部分要特别注意,除了实现功能代码外,还需自己手动添加一些其他的代码(Qt Creator可以自动添加). 我们需要在2个地方添加代码. 第1个是在addressbo ...

  8. LC 738. Monotone Increasing Digits

    Given a non-negative integer N, find the largest number that is less than or equal to N with monoton ...

  9. 线程池使用Callable示例【我】

    实际工作中可以把下面的代码直接拿过去改改即可 package threadtest; import java.util.ArrayList; import java.util.HashMap; imp ...

  10. Ubuntu 安装 docker,并上传到dockerhub

    一.安装Docker apt-get -y install docker.io 链接: ln -sf /usr/bin/docker.io /usr/local/bin/docker 检查docker ...