原題鏈接 Making the Grade Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6861 Accepted: 3176 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: NLines 2..N+1: Line i+1 contains a single integer elevation: AiOutput
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 Source
USACO 2008 February Gold
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 2000 + 10;const int INF = 0x3f3f3f3f;int dp[2][maxn],a[maxn],b[maxn];// a數組是原數組,b數組是a數組排序后的數組// 實際上a[i]變化后的結果就是成為b數組中某個位置的一個值而已,所以我們的定義dp[i][j]為在前i-1個已經// 有序的數組中將當前位置變化為b[j]位置的數的最小花費,由于dp[i-1][k]代表的序列已經有序(0<=k<=j),// 所以只需要考慮當前改變的消耗,dp[i][j] = min{dp[i-1][k]} + | a[i] - b[j] | 0<=k<=j// 當然其實由于引入了前j-1最小其實我們還可以把dp寫成一維的形式int _abs(int x){ return x > 0 ? x : -x;}bool cmp(int x,int y){ return x > y ? true : false;}int main(){ int n; while(scanf("%d",&n)==1){ for(int i=0;i<n;i++) {scanf("%d",&a[i]);b[i]=a[i];} int res = INF; memset(dp,0,sizeof(dp)); sort(b,b+n);//先處理升序的情況 for(int i=0;i<n;i++){ int PRe_min = dp[(i+1)&1][0]; dp[i&1][0] = dp[(i+1)&1][0] + _abs(a[i] - b[0]); for(int j=1;j<n;j++){ pre_min = min(pre_min,dp[(i+1)&1][j]); dp[i&1][j] = pre_min + _abs(a[i] - b[j]); } } for(int i=0;i<n;i++) res = min(res,dp[(n-1)&1][i]); memset(dp,0,sizeof(dp)); sort(b,b+n,cmp);//再處理降序的情況 for(int i=0;i<n;i++){ int pre_min = dp[(i+1)&1][0]; dp[i&1][0] = dp[(i+1)&1][0] + _abs(a[i] - b[0]); for(int j=1;j<n;j++){ pre_min = min(pre_min,dp[(i+1)&1][j]); dp[i&1][j] = pre_min + _abs(a[i] - b[j]); } } for(int i=0;i<n;i++) res = min(res,dp[(n-1)&1][i]); cout << res << endl; } return 0;}新聞熱點
疑難解答