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个算法,计算出将 ...
 
随机推荐
- C++中find_if
			
总结:find_if针对查找的对象中包含指针需要进行比较 find则更偏向于普通的数值或者字符比较 两者都可以应用于自定义的类,只需在类中重载==运载符 函数调用符()说白了其实就是代替函数指针,调用 ...
 - instanceof 和 typeof
			
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链 function Person(){ Person.prototype.dan ...
 - IDEA 调整 VM 配置文件(64位)
			
64 位操作系统中 8G 内存以下的机子或是静态页面开发者是无需修改的. 64 位操作系统且内存大于 8G 的, 如果你是开发大型项目. Java 项目或是 Android 项目,建议进行修改 . 1 ...
 - sFlow-rt安装部署
			
sFlow技术是一种以设备端口为基本单元的数据流随机采样的流量监控技术,不仅可以提供完整的第二层到第四层甚至全网范围内的实时流量信息,而且可以适应超大网络流量(如大于10Gbit/s)环境下的流量 ...
 - UVA-1364.Knights of the Round Table 无向图BCC
			
题目链接:https://vjudge.net/problem/UVA-1364 题意:有n个人参加会议,互相憎恨的人不能坐在相邻的位置,并且每个会议参加的人数必须是奇数,求有多少个人不能参加任何一个 ...
 - CentOS 7安装配置Samba服务器
			
CentOS 7安装配置Samba服务器 CentOS 7下Samba服务器安装配置过程笔记. 假设我们有这样一个场景 共享名 路径 权限 SHAREDOC /smb/docs 所有人员包括来宾均可以 ...
 - java进行3DES加解密
			
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.Secre ...
 - 利用PHP脚本辅助MySQL数据库管理5-检查异常数据
			
<?php $dbi = new DbMysql; $dbi->dbh = 'mysql://root:mysql@127.0.0.1/coffeetest'; $map = array( ...
 - MVC 开发模式
			
1.M:Model 模型:实体类和业务和dao 2.V:view 视图:JSP 3.C:Controller 控制器:servlet 3.1 作用:视图和逻辑分离 4.MVC适用场景:大型项目开 ...
 - Codeforces Round #543 (Div. 2) D 双指针 + 模拟
			
https://codeforces.com/contest/1121/problem/D 题意 给你一个m(<=5e5)个数的序列,选择删除某些数,使得剩下的数按每组k个数以此分成n组(n*k ...