[HDU] 3507Print Article print article (slope optimization)

[HDU] 3507Print Article print article (slope optimization)

Time Limit: 9000/3000 MS (Java/Others)
Memory Limit: 131072/65536 K (Java/Others)

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
Insert picture description here
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

translation

Print article

Time limit: 9000/3000 MS (Java/Other)
Memory limit: 131072/65536 K (Java/Other)

Problem Description

Zero's old printer sometimes does not work properly. As it is an antique, he still likes to use it to print objects. But it is too old to work for a long time, it will definitely wear out, so Zero uses the cost to evaluate the degree.
One day, Zero wants to print an article containing N words, and the printing cost of each word i is Ci. Moreover, Zero knows that printing k words in a line will cost
Insert picture description here
M a constant.
Now, Zero wants to know the lowest cost in order to arrange the merchandise perfectly.

enter

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

Output

A number that represents the minimum cost of printing the article.

Sample input

5 5
5
9
5
7
5

Sample output

230

Ideas

The meaning of the question is very clear, that is, the output sequence a[n], the cost of each continuous output is the square of the digital sum of the continuous output plus the constant M.
Let us find the minimum value of this cost.

Let dp[i] denote the minimum cost of outputting the first i, then the DP equation is as follows:

dp[i]= min{ dp[j]+(sum[i]-sum[j])^2 +M } 0<j<i

Among them, sum[i] represents the sum of the first i items of the number.

I believe we can understand the above equation.

The complexity of solving the above equation directly is O(n^2)

For a scale of 500,000, it is obviously overtime. The following explains how to use the slope to optimize the DP to reduce the complexity by one dimension.
We first assume that when calculating dp[i], k<j, j point is better than k point.
That is, dp[j]+(sum[i]-sum[j])^2+M <= dp[k]+(sum[i]-sum[k])^2+M;
so-called j is better than k That is, the value in the DP equation is smaller.
It is easy to organize the above equations:
[(dp[j]+sum[j]*sum[j])-(dp[k]+sum[k]*sum[k] )] / 2(sum[j]-sum[k]) <=sum[i].
Note that the positive and negative should be considered in the finishing, which involves the direction of the inequality sign.
On the left, we find that if we make: yj=dp[j]+sum[j] sum[j] xj=2 sum[j]
then it becomes a slope expression: (yj-yk)/(xj-xk) <= sum[i];
And the right side of the inequality is increasing.
So we can see the following two points: Let g[k,j]=(yj-yk)/(xj-xk)

First: If the above inequality is true, then j is better than k, and as i increases, the above inequality must be true, that is, when calculating the DP value for i, j is better than k. Then k can be eliminated.

Second: If k<j<i and g[k,j]>g[j,i] then j can be eliminated.

Assuming that g[j,i]<sum[i] is that i is better than j, then j has no value

On the contrary, if g[j,i]>sum[i] then there is also g[k,j]>sum[i] then k is better than j then j can be eliminated

It is maintained through a queue.

Code

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int c[500010],f[500010],sum[500010],que[500010],l,r;
int js(int x,int y)
{
    
    
    return f[x]+sum[x]*sum[x]-f[y]-sum[y]*sum[y];
}
int main()
{
    
    
	int n,m,i;
	while(scanf("%d%d",&n,&m)==2)
	{
    
    
		for(sum[0]=0,i=1;i<=n;i++)
			scanf("%d",&c[i]),sum[i]=sum[i-1]+c[i];
		memset(f,0,sizeof(f));
		for(l=r=0,que[0]=0,i=1;i<=n;i++)
		{
    
    
			for(;l<r&&js(que[l+1],que[l])<=((sum[i]*(sum[que[l+1]]-sum[que[l]]))<<1);l++);//出队,删除不符合条件的数 
			f[i]=f[que[l]]+m+(sum[i]-sum[que[l]])*(sum[i]-sum[que[l]]);
			for(;l<r&&js(i,que[r])*(sum[que[r]]-sum[que[r-1]])<=js(que[r],que[r-1])*(sum[i]-sum[que[r]]);r--);
			que[++r]=i;//入队 
		}
		printf("%d\n",f[n]);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_46975572/article/details/114901539