POJ3666_Making the Grade_DP

来源:互联网 发布:闭关锁国知乎 编辑:程序博客网 时间:2024/06/07 01:26

Making the Grade
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6994 Accepted: 3234

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

|AB1| + |AB2| + ... + |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

71324539

Sample Output

3


一条土路上有n段,每一段的高度可能各不相同。现要求在一部分路上增加一些土或减少一些土,使这条路的高度变成 单调不减少 或 单调不增加。求改动的土的最小值。


/***********************************DP题都做了十几条了,这个转移方程还是没写出来,感觉自己真的好弱啊。。。对于前i个数,我们需要关心的有两个值1.把它变成单调序列需要的土,越少越好2.第i个数的大小,越小越好于是dp[i][j]表示考虑前i个数,第i个数是j时,至少需要的土第i个数是j时最少需要的土,就等于j和a[i]差的绝对值+ 第i-1个数小于等于j时至少需要土的最小值即转移方程为:dp[i][j]=abs(j-a[i])+min(dp[i-1][k])k <= j到这里问题就基本解决了。但是因为a[i]的范围太大了,这样枚举k时就会TLE。这里需要离散化优化搞一个数组b,将a中的元素复制进去,然后排序。对于每个ij转移时,只要检查b中小于j的元素就可以了或者可以进一步省去遍历过程对于dp[i-1][j],维护一个最小值每次直接加最小值就可以了***********************************/#include<cstdio>#include<iostream>#include<algorithm>using namespace std;const int maxn = 2010;long long inf = 2147483646;long long dp [maxn][maxn];int a [maxn], b [maxn];int n;int main (){scanf("%d", &n);for(int i= 1; i<= n; i++){scanf("%d", a+i);b[i] = a[i];}sort(b+1, b+n+1);for(int i= 1; i<= n; i++){long long m = dp[i-1][1];for(int j= 1; j<= n; j++){m = min(m, dp[i-1][j]);dp[i][j] = abs(a[i] - b[j]) + m;}}long long ans = inf;for(int i= 1; i<= n; i++)ans = min(ans, dp[n][i]);printf("%lld\n", ans);return 0;}


0 0
原创粉丝点击