HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的区间DP问题 d
p[i][j]表示前i个节点,分为j个区间的最优策略值 cost[i][j]为从i到j节点的策略值 所以dp[i][j] = min(dp[k-1][j-1] + cost[k][i]
但是复杂度太高了 可以优化的地方有: cost数组值得求取: 考虑到cost(i,j)=ΣAxAy (i≤x<y≤j) 而(Ai+...+Aj)^2=ΣAxAy (i≤x,y≤j) 于是可以得到: cost(i,j)=((Ai+...+Aj)^2-(Ai^2+...+Aj^2))/2 这是一个优化后线性n的等式 式子中的若干连续项的和与若干连续项的平方和 是可以用 前缀和 预先处理的, 所以设sum(i)=A1+...+Ai,sqsum(i)=A1^2+...+Ai^2, 将原式化为: cost(i,j)=((sum(j)-sum(i-1))^2-(sqsum(j)-sqsum(i-1)))/2
又因为是经典的区间DP问题所以可以用四边形不等式进行优化
设s[i][j]为dp[i][j]的前导状态dp[i][j] = dp[s[i][j][j-1] + cost[s[i][j]+1][j]之后我们枚举k的时候只要枚举s[i][j-1]<=k<=s[i+1][j],此时j必须从小到大遍历i必须从大到小。
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#define inf (1 << 30)
using namespace std;
const int maxn = 1e3 + 1e2;
int dp[maxn][maxn];
int s[maxn][maxn];
//设s[i][j]为dp[i][j]的前导状态
//dp[i][j] = dp[s[i][j][j-1] + cost[s[i][j]+1][j]
//之后我们枚举k的时候只要枚举
//s[i][j-1]<=k<=s[i+1][j],此时j必须从小到大遍历
//i必须从大到小。
int cost[maxn][maxn];
int sum[maxn],powsum[maxn];
int a[maxn];
/*int get_cost(int l,int r)
{
if(r < l)return 0;
return ((sum[r] - sum[l-1]) * (sum[r] - sum[l-1]) - (powsum[r] - powsum[l-1])) / 2;
}*/
void init()
{
memset(sum,0,sizeof(sum));
memset(powsum,0,sizeof(powsum));
memset(cost,0,sizeof(cost));
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{ if(n == m && n == 0)break;
init();
//m++;
//前缀和处理
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
sum[i] = sum[i-1] + a[i];
powsum[i] = powsum[i-1] + a[i] * a[i];
} /*for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
{
if(j < i) cost[i][j] = 0;
else cost[i][j] = cost[i][j-1] + a[j] * (sum[j-1] - sum[i-1]);
}*/
//特殊值预处理
//这里没有m++但是0代表分一块
for(int i = 0;i <= n;i++)
{
dp[i][0] = cost[1][i];
// dp[i][0] = get_cost(1,i);
s[i][0] = 0;
s[n+1][i] = n;//外面的界限出界后的特殊处理
}
//区间DP & 四边形不等式
for(int j = 1;j <= m;j++)//分几部分
{
for(int i = n;i >= 1;i--)//前n个节点
{
dp[i][j] = inf;
for(int k = s[i][j-1];k <= s[i+1][j];k++)
{
if(dp[i][j] > dp[k][j-1] + get_cost(k+1,i))
{
dp[i][j] = dp[k][j-1] + get_cost(k+1,i);
s[i][j] = k;//确定上一个状态
}
}
}
}
printf("%d\n",dp[n][m]);
}
return 0;
}
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化的更多相关文章
- 区间DP石子合并问题 & 四边形不等式优化
入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...
- 区间dp+四边形不等式优化
区间dp+四边形优化 luogu:p2858 题意 给出一列数 \(v_i\),每天只能取两端的数,第 j 天取数价值为\(v_i \times j\),最大价值?? 转移方程 dp[i][j] :n ...
- [51nod 1022] 石子归并v2 [dp+四边形不等式优化]
题面: 传送门 思路: 加强版的石子归并,现在朴素的区间dp无法解决问题了 首先我们破环成链,复制一条一样的链并粘贴到原来的链后面,变成一个2n长度的序列,在它上面dp,效率O(8n^3) 显然是过不 ...
- hdu 2829 Lawrence(四边形不等式优化dp)
T. E. Lawrence was a controversial figure during World War I. He was a British officer who served in ...
- HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)
题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程 ...
- CSP 201612-4 压缩编码 【区间DP+四边形不等式优化】
问题描述 试题编号: 201612-4 试题名称: 压缩编码 时间限制: 3.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一段文字,已知单词a1, a2, …, an出现的频率分别t1 ...
- 二叉搜索树 [四边形不等式优化区间dp]
二叉搜索树 [四边形不等式优化区间dp] 题目描述 有 \(n\) 个结点,第 \(i\) 个结点的权值为 \(i\) . 你需要对它们进行一些操作并维护一些信息,因此,你需要对它们建立一棵二叉搜索树 ...
- 区间dp之四边形不等式优化详解及证明
看了那么久的四边形不等式优化的原理,今天终于要写一篇关于它的证明了. 在平时的做题中,我们会遇到这样的区间dp问题 它的状态转移方程形式一般为dp[i][j]=min(dp[i][k]+dp[k+1] ...
- 区间DP的四边形不等式优化
今天上课讲DP,所以我学习了四边形不等式优化(逃 首先我先写出满足四边形不等式优化的方程:
随机推荐
- istream_iterator和ostream_iterator
总结: istream_iterator<T>in(strm);T指明此istream_iterator的输入类型,strm为istream_iterator指向的流 提供了输入操作符(& ...
- javascript数组中数字和非数字下标的区别(转)
http://blog.csdn.net/qq_27461663/article/details/52014911 考完试后闲来无事,想起好多天没写js了,于是打算实践一下最近看到的一些好玩的点子.结 ...
- 20172306《Java程序设计与数据结构》第十周学习总结
20172306<Java程序设计>第十周学习总结 教材学习内容总结 本章主要的讲的是集合有关的知识: 1.集合与数据结构 - 集合是一种对象,集合表示一个专用于保存元素的对象,并该对象还 ...
- socket 长连接
实现: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的. 如果,长时间未发送维持连接包,服务端程序将断开连接. 服务端: 由于客户端会定时(keepAliveDelay毫秒)发送 ...
- Java的反射技术
什么是反射机制 Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能调用它的任意属性和方法.这种动态获取信息以及动态调用对象属性和方法的即使称为J ...
- Vue 不同环境配置相应的 API 地址
我使用的是 Vue + ElementUI 进行构建的项目,在开发过程中,使用的是前后端分离的模式,所以经常会出现多环境配置信息,尤其是 Api 接口地址的配置,如果在代码中使用判断的方式,感觉不友好 ...
- [Hbase]Hbase章3 Hbase单点故障
很长一段时间以来,一个region同一时间只能在一台RS(Region Server)中打开.如果一个region同时在多个RS上打开,就是multi-assign问题,会导致数据不一致甚至丢数据的情 ...
- c++11 多线程依次打印ABC
并发 练习代码 #include <thread> #include <vector> #include <mutex> #include <iostream ...
- windows一键配置 php mysql apache 记录
记录下 方便查找(最近机器老重装 资料丢失严重) wamp http://www.wampserver.com/en/#download-wrapper https://sourceforge.net ...
- Python之异常处理和socket套接字连接7
一.异常处理 1)异常处理的使用意义 什么是异常处理 异常是程序发生错误的信号,即程序一旦出错就会立刻产生一个异常,如果该异常没有被处理 那么异常就抛出来,程序的运行也随之终止 异常分为三部分: 异常 ...