B - Lawrence HDU - 2829 斜率dp dp转移方程不好写
B - Lawrence
这个题目我觉得很难,难在这个dp方程不会写。
看了网上的题解,看了很久才理解这个dp转移方程
dp[i][j] 表示前面1~j 位并且以 j 结尾分成了 i 段的最小权值和
再定义一个数组 w[a,b] 表示 a到b 的权值和,注意这个不是前缀和,而是题目给的那种权值和
比如 a 到 b 是4 5 1 2 Its Strategic Value is 4*5 + 4*1 + 4*2 + 5*1 + 5*2 + 1*2 = 49.
w[a,b]=49
然后再定义一个val[i] ==w[1,i] 意思就是前缀权值和 val[i]=val[i-1]+sum[i-1]*a[i]
因为这个w[a,b]不好直接推出来,但是可以借助前缀来推。
求w[a+1,b]=val[b]-val[a]-(sum[b]-sum[a])*sum[a]
然后这个dp方程就可以推出来了
dp[i,j]=min(dp[i-1,k]+w[k+1,j])
但是这个直接暴力n^3肯定是过不了的,所以需要优化,这个式子是不是和之前推过的斜率优化的式子很像。
如果在dp[i-1,k]之外还存在k这个值,一般都是可以用斜率优化来优化这个dp的。
然后就可以推出和之前一样的式子(之前指的是D - Pearls HDU - 1300 斜率dp+二分 斜率dp A - Print Article HDU - 3507)
令 F[h]=dp[i-1][h]-val[h]+sum[h]*sum[h]
所以G[h,k]=(F[h]-F[k)/(sum[h]-sum[k])<sum[j]
然后就是一样的推导了
如果存在 i>j>k G[i,j]>G[j,k]
1 G[i,j]>Gj,k]>sum[t] k 比 j 优 ,j 比 i 优
2 G[i,j]>sum[t]>G[j,k] 那么 j 比 i 优,j 比 k 优
3 sum[t]>G[i,j]>G[j,k] i 比 j 优 j 比k 优
如果是 i > j > k G[i,j]<G[j,k]
1 G[i,j]<G[j,k]<sum[t] j 比 k 优 i 比 j 优
2. G[i,j]<sum[t]<G[j,k] i 比 j 优 k 比 j 优
3 sum[t]<G[i,j]<G[j,k] j 比 i 优 k 比 j 优
这种情况之下,j 肯定是要被排除的,所以如果从后面插入 i 的时候 前面的 j 如果和它构成的斜率小于这个数和之前的那个数构成的斜率,
那么这个 j 肯定是不要的。
因为这个前缀和sum是单调的,所以可以用单调队列优化这个dp。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5 + ;
typedef long long ll;
ll dp[][], sum[], val[], a[];
int que[maxn]; ll up(int i,int j,int k)
{
return dp[i - ][j] - val[j] + sum[j] * sum[j] - (dp[i - ][k] - val[k] + sum[k] * sum[k]);
} ll down(int j,int k)
{
return sum[j] - sum[k];
} ll DP(int i,int j,int k)
{
return dp[i - ][k] + val[j] - val[k] - (sum[j] - sum[k])*sum[k];
} int main()
{
int n, m;
while (scanf("%d%d", &n, &m) && (n + m)) {
sum[] = ;
val[] = ;
for (int i = ; i <= n; i++) {
scanf("%lld", &a[i]);
sum[i] = sum[i - ] + a[i];
val[i] = val[i - ] + sum[i - ] * a[i];
}
for (int i = ; i <= n; i++) dp[][i] = val[i];//注意这个题目的初始化
for (int i = ; i <= m + ; i++) {
int head = , tail = ;//注意dp[i,j]的定义是以j结尾分成了i块的最小价值
que[tail++] = i - ;//因为下一段要分成i块,所以前面最少也占了i-1个数,而后面又有可能全部分成一块,注意这种情况不要漏掉
for (int j = i; j <= n; j++) {//注意这个j必须要从i开始
while (head + < tail&&up(i, que[head + ], que[head]) <= sum[j] * down(que[head + ], que[head])) head++;
dp[i][j] = DP(i, j, que[head]);
while (head + < tail&&up(i, j, que[tail - ])*down(que[tail - ], que[tail - ]) <= up(i, que[tail - ], que[tail - ])*down(j, que[tail - ])) tail--;
que[tail++] = j;
}
}
printf("%lld\n", dp[m + ][n]);
}
return ;
}
B - Lawrence HDU - 2829 斜率dp dp转移方程不好写的更多相关文章
- HDU 2829 斜率优化DP Lawrence
题意:n个数之间放m个障碍,分隔成m+1段.对于每段两两数相乘再求和,然后把这m+1个值加起来,让这个值最小. 设: d(i, j)表示前i个数之间放j个炸弹能得到的最小值 sum(i)为前缀和,co ...
- hdu 2829 斜率DP
思路:dp[i][x]=dp[j][x-1]+val[i]-val[j]-sum[j]*sum[i]+sum[j]*sum[j]; 其中val[i]表示1~~i是一段的权值. 然后就是普通斜率dp做法 ...
- HDU 4258 斜率优化dp
Covered Walkway Time Limit: 30000/10000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- hdu 3045 斜率优化DP
思路:dp[i]=dp[j]+sum[i]-sum[j]-(i-j)*num[j+1]; 然后就是比较斜率. 注意的时这里j+t<=i: #include<iostream> #in ...
- hdu 3669(斜率优化DP)
Cross the Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others) ...
- Print Article HDU - 3507 -斜率优化DP
思路 : 1,用一个单调队列来维护解集. 2,假设队列中从头到尾已经有元素a b c.那么当d要入队的时候,我们维护队列的下凸性质, 即如果g[d,c]<g[c,b],那么就将c点删除.直到找到 ...
- HDU 3507 斜率优化dp
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- HDU 3507斜率优化dp
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- HDU 3507 斜率优化 DP Print Article
在kuangbin巨巨博客上学的. #include <iostream> #include <cstdio> #include <cstring> #includ ...
随机推荐
- web.xml配置参数context-param和init-param的区别
web.xml配置参数context-param和init-param的区别 (2009-04-13 10:29:01) 转载▼ 标签: 杂谈 分类: JavaEE web.xml里面可以定义两种参数 ...
- HttpWebRequest在Post的时候,遇到特殊符号+号(加号)变成空格了
今天在调用一个外部接口的时候遇到一个问题,外部接口说要用FOMR的POST方法提交. OK,没问题,我加了个ASPX页面,里面加了个FORM表单和一些元素,提交,返回值成功.注意看下面这一句:但返回值 ...
- 「日常开发」记一次因使用Date引起的线上BUG处理
生活中,我们需要掌控自己的时间,减少加班,提高效率:日常开发中,我们需要操作时间API,保证效率.安全.稳定.现在都2020年了,了解如何在JDK8及以后的版本中更好地操控时间就很有必要,尤其是一次线 ...
- D - Three Integers CodeForces - 1311D
题意: a<=b<=c 输出A,B,C要求B是A的倍数,C是B的倍数,并且输出a,b,c变成A,B,C需要的最小次数. 题解:写了半天的二分,后来发现思路错了,,,暴力就能过.. 三层fo ...
- sysbench安装和使用
sysbench是一款测试工具 主要包括以下几种方式的测试: 1.cpu性能 2.磁盘io性能 3.调度程式性能 4.内存分配及传输速度 5.POSIX线程性能 6.数据库性能(OLTP基准测试)现在 ...
- python 进阶篇 迭代器和生成器深入理解
列表/元组/字典/集合都是容器.对于容器,可以很直观地想象成多个元素在一起的单元:而不同容器的区别,正是在于内部数据结构的实现方法. 所有的容器都是可迭代的(iterable).另外字符串也可以被迭代 ...
- 解决Typecho Gravatar头像加载缓慢的问题
前言 Typecho评论默认使用的是Gravatar头像,但因为Gravatar网站总是被墙,导致页面加载被拖慢,而且加载半天也还是个裂图,太影响心情,所以我们可以不使用Gravatar头像,换成另一 ...
- GOLANG 闭包和普通函数的区别
闭包和匿名函数是一回事 闭包使用完毕之后不会自动释放,值依然存在 普通函数调用完毕后,值会自动释放
- bootstrop日历
https://blog.csdn.net/cuixiaobo521/article/details/77880633
- FPM制作Nginx的RPM软件包
FPM制作Nginx的rpm软件包 FPM相关参数-s:指定源类型-t:指定目标类型,即想要制作为什么包-n:指定包的名字-v:指定包的版本号-C:指定打包的相对路径-d:指定依赖于哪些包-f:第二次 ...