POJ 3666 Making the Grade(dp)

Making the Grade

Time Limit: 1000MS


Memory Limit: 65536K

Total Submissions: 5207


Accepted: 2455

Description

A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would like. His cows do not mind climbing up or down a single slope, but they are not fond of an alternating succession of hills and valleys. FJ would like to add and remove dirt from the road so that it becomes one monotonic slope (either sloping up or down).

You are given N integers A1, ... , AN (1 ≤ N ≤ 2,000) describing the elevation (0 ≤ Ai ≤ 1,000,000,000) at each of N equally-spaced positions along the road, starting at the first field and ending at the other. FJ would like to adjust these elevations to a new sequence B1, . ... , BN that is either nonincreasing or nondecreasing. Since it costs the same amount of money to add or remove dirt at any position along the road, the total cost of modifying the road is

|A1 - B1| + |A2 - B2| + ... + |AN - BN |

Please compute the minimum cost of grading his road so it becomes a continuous slope. FJ happily informs you that signed 32-bit integers can certainly be used to compute the answer.

Input

* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains a single integer elevation: Ai

Output

* Line 1: A single integer that is the minimum cost for FJ to grade his dirt road so it becomes nonincreasing or nondecreasing in elevation.

Sample Input

7
1
3
2
4
5
3
9

Sample Output

3


题意:给出n个数字的序列,可以修改任意数字的值,让其变成非严格递增序列或者非严格递减序列,求最小的修改量是多少?


题解:什么左偏树,离散化dp统统不会啦(;′⌒`)。 dp也好艰难,一道入门题看了一晚上。 好啦,回正题。 这题虽然是说在求非严格递增或者非严格递减的情况下,但利用dp求解,两者没有区别。


dp[i][j] 表示对于前 i+1 个数字,第j个小的数字为序列最后一个元素时的最小修改量。

根据题中给出的原序列,我们确定元素间的大小关系,对应编号为 p[i]。

dp[i][j] = min( dp[i-1][k] {0<k<n} ) + abs(a[i]-a[p[j]])


二维数组虽然能通过此题,但内存占用量很大,改成滚动数组更合适。


代码如下:


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll __int64
using namespace std;
ll a[2020],b[2020];
ll dp[2][2020];

int main()
{
	int n,i,j;
	while(scanf("%d",&n)!=EOF)
	{
		for(i=0;i<n;++i)
		{
			scanf("%I64d",&a[i]);
			b[i]=a[i];
		}
		sort(b,b+n);
		for(i=0;i<n;++i)
			dp[0][i]=abs(a[1]-b[i]);
		for(i=1;i<n;++i)
		{
			ll temp=dp[(i-1)%2][0];
			for(j=0;j<n;++j)
			{
				temp=min(dp[(i-1)%2][j],temp);
				dp[i%2][j]=temp+abs(a[i]-b[j]);
			}
		}
		ll ans=dp[(n-1)%2][0];
		for(i=0;i<n;++i)
			ans=min(ans,dp[(n-1)%2][i]);
		printf("%I64d\n",ans);
	}
	return 0;
}
 





你可能感兴趣的:(POJ 3666 Making the Grade(dp))