hdu3507_斜率dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3507

Print Article

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 9699    Accepted Submission(s): 3066

Problem Description

Zero has an old printer that doesn‘t work well sometimes. As it is antique, he still like to use it to print articles. But it is too old to work for a long time and it will certainly wear and tear, so Zero use a cost to evaluate this degree.
One day Zero want to print an article which has N words, and each word i has a cost Ci to be printed. Also, Zero know that print k words in one line will cost

M is a const number.
Now Zero want to know the minimum cost in order to arrange the article perfectly.

Input

There are many test cases. For each test case, There are two numbers N and M in the first line (0 ≤ n ≤ 500000, 0 ≤ M ≤ 1000). Then, there are N numbers in the next 2 to N + 1 lines. Input are terminated by EOF.

Output

A single number, meaning the mininum cost to print the article.

Sample Input

5 5
5
9
5
7
5

Sample Output

230

推荐博客:http://blog.csdn.net/azheng51714/article/details/8214165

 1 //dp[i]=dp[j]+M+(sum[i]-sum[j])^2
 2 //设k<j<i, j比k决策好
 3 //dp[j]+M+(sum[i]-sum[j])^2<dp[k]+M+(sum[i]-sum[k])^2
 4 //(dp[j]+num[j]^2-(dp[k]+num[k]^2))/(2*(num[j]-num[k]))<sum[i]
 5 //dp[j]+num[j]^2-(dp[k]+num[k]^2))  GetUp()
 6 //2*(num[j]-num[k])  GetDown()
 7 #include <algorithm>
 8 #include <iostream>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cstdio>
12 #include <vector>
13 #include <ctime>
14 #include <queue>
15 #include <list>
16 #include <set>
17 #include <map>
18 using namespace std;
19 #define INF 0x3f3f3f3f
20 typedef long long LL;
21
22 int dp[500010], n, m, sum[500010], q[500010];
23 int GetDp(int i, int j)
24 {
25     return dp[j] + m + (sum[i]-sum[j])*(sum[i]-sum[j]);
26 }
27 int GetUp(int j, int k)//yj-yk的部分
28 {
29     return dp[j] + sum[j]*sum[j] - (dp[k]+sum[k]*sum[k]);
30 }
31 int GetDown(int j, int k)//xj-xk的部分
32 {
33     return 2 * (sum[j] - sum[k]);
34 }
35 int main()
36 {
37     while(~scanf("%d %d", &n, &m))
38     {
39         sum[0] = dp[0] = 0;
40         for(int i = 1; i <= n; i++){
41             scanf("%d", &sum[i]);
42             sum[i] += sum[i-1];
43         }
44         int head = 0, tail = 0;
45         q[tail++] = 0;
46         for(int i = 1; i <=n; i++)
47         {
48             while(head+1<tail && GetUp(q[head+1],q[head])<=sum[i]*GetDown(q[head+1],q[head]))
49                 head++;
50             dp[i] = GetDp(i, q[head]);
51             while(head+1<tail && GetUp(i, q[tail-1])*GetDown(q[tail-1],q[tail-2])<=GetUp(q[tail-1],q[tail-2])*GetDown(i,q[tail-1]))
52                 tail--;
53             q[tail++] = i;
54         }
55         printf("%d\n", dp[n]);
56     }
57     return 0;
58 }

时间: 2024-07-31 12:21:58

hdu3507_斜率dp的相关文章

bzoj 1597 斜率DP

1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5115  Solved: 1897[Submit][Status][Discuss] Description 农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <= 1,000,000; 1 <= 长 <= 1,000,000). 每块土地

bzoj 1492 [NOI2007]货币兑换Cash(斜率dp+cdq分治)

Description Input 第一行两个正整数N.S,分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来N 行,第K 行三个实数AK.BK.RateK,意义如题目中所述 Output 只有一个实数MaxProfit,表示第N 天的操作结束时能够获得的最大的金钱 数目.答案保留3 位小数. Sample Input 3 100 1 1 1 1 2 2 2 2 3 Sample Output 225.000 HINT 测试数据设计使得精度误差不会超过10-7.对于40%的测试数据,满足N

hdu3669之二维斜率DP

Cross the Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others) Total Submission(s): 4176    Accepted Submission(s): 748 Problem Description "Across the Great Wall, we can reach every corner in the world!" No

HNOI2008 玩具装箱toy (BZOJ1010,斜率dp)

传送门 1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MB Description P 教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维 容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的. 同时如果一个一维容器中有多个玩具,那么两件玩

bzoj 3156 防御准备(斜率DP)

3156: 防御准备 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 837  Solved: 395[Submit][Status][Discuss] Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战线花费值. Sample Input 10 2 3 1 5 4 5 6 3 1 2 Sample Output 18 HIN

[DP优化方法之斜率DP]

什么是斜率dp呢 大概就把一些单调的分组问题 从O(N^2)降到O(N) 具体的话我就不多说了 看论文: http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html 我自己也补充几句: 其实斜率dp有很多种打法 有凸包 有截距 有直接比较斜率的 因为我比较弱 所以的话就学最弱智的比较斜率的 听wph说截距很好理解 然后的话 讲课的时候scy说什么要证单调性什么鬼的 我在学的过程中好像没遇到就不管了 虽然我很弱 反正我能AC就行了

斜率dp cdq 分治

f[i] = min { f[j] + sqr(a[i] - a[j]) } f[i]= min { -2 * a[i] * a[j] + a[j] * a[j] + f[j] } + a[i] * a[i] 由于a[i]不是单调递增的,不能直接斜率dp. 考虑有cdq分治来做,复杂度(nlog2n) 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm&

hdu 3507 斜率dp

不好理解,先多做几个再看 此题是很基础的斜率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的规模显然是超时的.下面讲解下如何用斜率

HDU 2829 Lawrence (斜率DP)

斜率DP 设dp[i][j]表示前i点,炸掉j条边的最小值.j<i dp[i][j]=min{dp[k][j-1]+cost[k+1][i]} 又由得出cost[1][i]=cost[1][k]+cost[k+1][i]+sum[k]*(sum[i]-sum[k]) cost[k+1][i]=cost[1][i]-cost[1][k]-sum[k]*(sum[i]-sum[k]) 代入DP方程 可以得出 y=dp[k][j-1]-cost[1][k]+sum[k]^2 x=sum[k]. 斜率s