洛谷 P1880 [NOI1995]石子合并 题解
2024-10-21 06:21:31
P1880 [NOI1995]石子合并
题目描述
在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.
输入格式
数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.
输出格式
输出共2行,第1行为最小得分,第2行为最大得分.
输入输出样例
输入 #1
4
4 5 9 4
输出 #1
43
54
【思路】
区间DP
【核心思路】
又是围成一个圈
所以处理方式很显然
就是在原来的序列后面放一个和原来序列一样的序列就可以了
这样2-n+1区间就是存在的
而且是那1-n个数
就是起点不同而已
每次合并后的值等于原来合并的价值
加上
这次合并的石子数
如果只用一个二维数组f[i][j]的话显然是没有办法保存的
所以可以利用一个很优美的东西
前缀和
利用前缀和可以求出某个区间的石子数
也就是可以知道每次石子合并可以新得到的值
那么就可以只用f[i][j]来存i-j区间内
合并石子的最值就好了
【DP式】
DP方程式:
f1[i][j] = max(f1[i][j],f1[i][k] + f1[k + 1][j] + cost[i][j])
f2[i][j] = min(f2[i][j],f2[i][k] + f2[k + 1][j] + cost[i][j])
(一个求区间最大值,一个求区间最小值)
这个区间的最值就等于分成两个小区间合并起来之后的最值
【最终结果】
最后结果
自然是比较i-i + n - 1这个区间啦
因为圈不同于一条线的就是可以任选起点
所以要比较以每一个作为起点时的最值
输出就好了
【完整代码】
#include<iostream>
#include<cstdio>
using namespace std;
const int Max = 206;
int f1[Max][Max];
int f2[Max][Max];
int a[Max];
int sum[Max];
int cost[Max][Max];
int main()
{
int n;
cin >> n;
for(register int i = 1;i <= n;++ i)
cin >> a[i],a[i + n] = a[i];
for(register int i = 1;i <= n * 2;++ i)
sum[i] = sum[i - 1] + a[i];
for(register int i = 1;i <= n * 2;++ i)
for(register int j = i;j <= n * 2;++ j)
cost[i][j] = sum[j] - sum[i - 1];
for(register int len = 1;len <= n;++ len)
{
for(register int i = 1;i + len - 1 <= n * 2;++ i)
{
int j = i + len - 1;
if(i != j)
f2[i][j] = 999999999;
for(register int k = i;k < j;++ k)
f1[i][j] = max(f1[i][j],f1[i][k] + f1[k + 1][j] + cost[i][j]),
f2[i][j] = min(f2[i][j],f2[i][k] + f2[k + 1][j] + cost[i][j]);
}
}
int M = 0;
int MM = 0x7fffffff;
for(register int i = 1;i <= n;++ i)
M = max(M,f1[i][i + n - 1]),
MM = min(MM,f2[i][i + n - 1]);
cout << MM << endl << M << endl;
return 0;
}
最新文章
- npm更新到最新版本的方法
- npm穿墙
- xcode archive导出ipa时重签名
- string与char* 互相转换以及周边问题
- USB枚举详细过程剖析(转)
- mysql 互为主从复制常见问题
- HTTP 错误 403.14 - Forbidden的解决办法
- [0] 解决版本冲突-使用SVN主干与分支功能
- SQLMap安装步骤
- Service Worker和HTTP缓存
- node安装教程
- 巩固java(一)----java与对象
- yii2下载
- StringBuilder and StringBuffer
- 20165237 2017-2018-2 《Java程序设计》第7周学习总结
- CentOS 7.0关闭服务器的防火墙服务命令
- DP的各种优化(动态规划,决策单调性,斜率优化,带权二分,单调栈,单调队列)
- 补码与C++的应用
- git hub 使用心得
- code vs 2602 最短路径问题
热门文章
- GreenPlum 最佳实践
- DevExpress中GridColumnCollection实现父子表数据绑定
- Idea中类实现Serializable接口 引入 serialVersionUID
- .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
- vscode入门使用教程(页面调试)
- Date类的相关方法记录
- Redis基础用法
- 移动应用开发中AppID、AppKey、AppSecret
- Zabbix Documentation 4.0
- django引用模板报错Template file &#39;index.html&#39; not found