hdu 3507 斜率优化】的更多相关文章

我的第一道斜率优化. 就这道题而言,写出原始的方程: dp[i] = min{ dp[j] + (sum[i]-sum[j])2  + M | j in [0,i) } O(n^2)的复杂度肯定超时,要么优化转移,要么重写方程. 斜率优化的思想就是减少不必要的枚举(即不枚举肯定不会成为决策点的j). 我们考虑两个位置p<q<i “选择q比选择p优” 当且仅当 dp[q]+(sum[i]-sum[q])2+M < dp[p]+(sum[i]-sum[p])2+M 化简右边即: [ (dp[…
思路 : 1,用一个单调队列来维护解集. 2,假设队列中从头到尾已经有元素a b c.那么当d要入队的时候,我们维护队列的下凸性质, 即如果g[d,c]<g[c,b],那么就将c点删除.直到找到g[d,x]>=g[x,y]为止,并将d点加入在该位置中. 3,求解时候,从队头开始,如果已有元素a b c,当i点要求解时,如果g[b,a]<sum[i], 那么说明b点比a点更优,a点可以排除,于是a出队.最后dp[i]=getDp(q[head]). #include<bits/std…
Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 11141    Accepted Submission(s): 3393 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu…
Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 12185    Accepted Submission(s): 3733 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu…
在kuangbin巨巨博客上学的. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; + ; int d[maxn], Q[maxn], sum[maxn]; int head, tail; int n, M; int inline dx(int i, int j) { return sum[j] - sum[i…
不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个的最小费用,那么有如下的DP方程: dp[i]= min{ dp[j]+(sum[i]-sum[j])^2 +M }  0<j<i 其中 sum[i]表示数字的前i项和. 相信都能理解上面的方程. 直接求解上面的方程的话复杂度是O(n^2) 对于500000的规模显然是超时的.下面讲解下如何用斜率…
Cross the Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)Total Submission(s): 4479    Accepted Submission(s): 812 Problem Description “Across the Great Wall, we can reach every corner in the world!” Now the…
Covered Walkway Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1496    Accepted Submission(s): 602 Problem Description Your university wants to build a new walkway, and they want at least p…
题意:n个数之间放m个障碍,分隔成m+1段.对于每段两两数相乘再求和,然后把这m+1个值加起来,让这个值最小. 设: d(i, j)表示前i个数之间放j个炸弹能得到的最小值 sum(i)为前缀和,cost(i)为前i个数两两相乘之和. 则有状态转移方程: 设0 ≤ l < k < i,且k比l更优,有不等式: 整理得到,注意不等号方向: 最后变成了斜率的形式,下面就用一个队列维护即可. #include <iostream> #include <cstdio> #inc…
思路:dp[i]=dp[j]+sum[i]-sum[j]-(i-j)*num[j+1]; 然后就是比较斜率. 注意的时这里j+t<=i: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define Maxn 400010 #define LL __int64 using namespace std; LL…