HDU3506环形石子合并问题
线性的石子合并问题比较好理解,环形的转成线性的方法就是扩展数组
1 2 3 . . . n 1 2 3 ... n
依据是我们最优的取值可以是 1 --- n也能是 2 --- n + 1,所以完全可以线性来做
for(int i = 1;i <= 2 * n;i++)
{
if(i <= n) scanf("%d",&a[i]);
else a[i] = a[i-n]; sum[i] = sum[i-1] + a[i];
}
都快忘记了线性石子合并的问题了
未涉及四边形不等式优化前
dp[i][j]表示i到j元素区间内的权值和,sum[i][j]辅助dp[i][j]的状态转移
dp[i][j] = dp[i][k] + dp[k + 1][j] + sum[i][j]
所以我们枚举起点i之前要枚举区间的长度 l
最后应用上四边形不等式
先来看看初始化问题
for(int i = 0;i <= 2*n;i++)
{
dp[i][i] = 0;
s[i][i] = i;
s[2*n][i] = 2 * n;
}
dp[i][i]仅仅一个元素权值为0——————权值根据题意来计算
s[i][i] 最优分界点 k = i
s[2*n][i] = 2 * n; 防止越界,规定一个上界,最高值也就是 2* n
好的,差不多啦,四边形不等式做到现在用的也很熟练了,还是得多练啊
/*
做的快忘得也挺快啊
石子问题
dp[i][j]表示的事从i到j的最优值
如何遍历j呢,就需要遍历区间的长度啦长度为1是无效的
*/ #include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#define inf (1 << 30)
using namespace std;
const int maxn = 2 * (1e3 + 10);
int dp[maxn][maxn];
int s[maxn][maxn];
int a[maxn];
int sum[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
sum[0] = 0;
for(int i = 1;i <= 2 * n;i++)
{
if(i <= n) scanf("%d",&a[i]);
else a[i] = a[i-n]; sum[i] = sum[i-1] + a[i];
} for(int i = 0;i <= 2*n;i++)
{
dp[i][i] = 0;
s[i][i] = i;
s[2*n][i] = 2*n;
} for(int l = 2;l <= n;l++)//区间长度
{
for(int i = 2 * n + 1 - l;i >= 1;i--)//起点
{
int j = i + l - 1;//终点
dp[i][j] = inf;
for(int k = s[i][j-1];k <= s[i+1][j];k++)
{
int tmp = dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1];
if(dp[i][j] > tmp)
{
dp[i][j] = tmp;
s[i][j] = k;
}
}
}
}
int ans = inf;
for(int i = 1;i <= n;i++)
{
ans = min(ans,dp[i][i + n - 1]);
}
printf("%d\n",ans);
}
return 0;
}
HDU3506环形石子合并问题的更多相关文章
- HDU 3506 (环形石子合并)区间dp+四边形优化
Monkey Party Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Tot ...
- HDU-3506 Monkey Party (环形石子合并)
题目大意:n堆石子围成一圈,每堆石子的块数已知,每次可以将相邻的两堆合并到一堆,块数变为两堆之和,代价也为两堆石子块数之和.求合并到一堆的最小代价. 题目分析:先通过将前n-1依次个移到第n个后面,将 ...
- RQNOJ 490 环形石子合并
题目链接:https://www.rqnoj.cn/problem/490 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一 ...
- 洛谷P1880 石子合并(环形石子合并 区间DP)
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- dp——环形石子合并(区间dp)
环形的解决很巧妙 #include <iostream> #include <cstring> #include <string> #include <map ...
- 四边形不等式优化_石子合并问题_C++
在动态规划中,经常遇到形如下式的状态转移方程: m(i,j)=min{m(i,k-1),m(k,j)}+w(i,j)(i≤k≤j)(min也可以改为max) 上述的m(i,j)表示区间[i,j]上的某 ...
- HRBUST - 1819 石子合并问题--圆形版(区间dp+环形+四边形优化)
石子合并问题--圆形版 在圆形操场上摆放着一行共n堆的石子.现要将石子有序地合并成一堆.规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆石子数记为该次合并的得分.请编辑计算出将n堆石子合并成一堆的 ...
- Luogu【P1880】石子合并(环形DP)
先放上luogu的石子合并题目链接 这是一道环形DP题,思想和能量项链很像,在预处理过程中的手法跟乘积最大相像. 用一个m[][]数组来存储石子数量,m[i][j]表示从第 i 堆石子到第 j 堆石子 ...
- P1880 [NOI1995]石子合并[环形DP]
题目来源:洛谷 题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将 ...
随机推荐
- shell判断文件后缀名是否为特定字符串
如果文件是 .css文件 或 .js文件,则进行处理. if [ "${file##*.}"x = "css"x ]||[ "${file##*.}& ...
- 基于稀疏表(Sparse Table)的RMQ(区间最值问题)
在RMQ的其他实现方法中,有一种叫做ST的算法比较常见. [构建] dp[i][j]表示的是从i起连续的2j个数xi,xi+1,xi+2,...xi+2j-1( 区间为[i,i+2j-1] )的最值. ...
- 糟糕的@@identity,SCOPE_IDENTITY ,IDENT_CURRENT
在某数据库里面,某甲用@@identity来获取最近插入的id值,当在多人环境,发生获取到null值的问题. 那么@@identity是否有存在的必要? 感觉像生个孩子,多了个指头. 有的数据库的ge ...
- ubuntu 下通过ftp命令下载文件
/*连接*/ $ ftp 192.168.180.2Connected to 192.168.180.2.Name (192.168.180.2:rivsidn): admin Password: ...
- js对象通过属性路径获取属性值 - getPropByPath
function getPropByPath(obj, path) { let tempObj = obj; path = path.replace(/\[(\w+)\]/g, '.$1'); pat ...
- Oracle 12c的可插拔数据库PDB
1. 默认安装之后会有一个可插拔数据库:pdborcl 2. 启动根容器: [oracle@eric ~]$ export ORACLE_SID=orcl [oracle@eric ~]$ sqlpl ...
- ios 内存管理与property copy strong weak assign
- (void)fun{ NSString* str = [[NSString alloc] initWithString:@"string"]; NSLog(@"% ...
- CSS-表格特有属性和定位
1.表格特有属性 1.边框合并 属性:border-collapse 取值: 1.separate 默认值,即分离边框模式 2.collapse 边框合并 2.边框边距 作用:设置单元格之间或单元格与 ...
- 使用kbmmw smart service 属性时的一个注意事项
kbmmw 5.0 以后支持smart service, 这个用起来非常方便,kbmmw 通过 定制属性来简化编程,可以参考我以前的文章.但是这个意味着使用单元引用一定要小心, 否则出了问题,都不知道 ...
- 使用delphi 10.2 开发linux 上的Daemon
delphi 10.2 支持linux, 而且官方只是支持命令行编程,目地就是做linux 服务器端的开发. 既然是做linux服务器端的开发,那么普通的命令行运行程序,然后等待开一个黑窗口的方式就 ...