Making the Grade POJ - 3666(离散化+dp)
題意:
給你n個山的高度,單獨的一個數可以任意加減,讓經過對每座山峰任意加減高度后變成遞增或遞減的序列時,求對每個數的相加或相減的數目的最小和。
題目:
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
分析:
前言:這道題糾結了好久,原因是我沒想到離散化,知道用離散化后,我還是轉不過來,認為經過增加或減少后,山峰的高度不為原始高度的任意一種,所以認為離散化不是最優的,其實到現在我還是這么認為,但由于山峰高度過高,哪怕離散化過后枚舉復雜度還是有o(n2n^{2}n2),所以我妥協了(在這里求助,如果有大犇有關于這道題離散化更好地理解,希望能給我一些幫助,嘻嘻)
1.這道題dp還是好理解的,即離散化過后每次枚舉當第i個山峰到達某山峰高度,dp[i][j]表示把前i個數變成單調增且第i個數變成原來第j大的數的最小代價。
2、把給定的山峰高度排好序,就成為其離散的遞增或遞減的高度。
3、對第一點進行與排好序的最小值的點進行比較,求得dp[0][j]要升到第j的高度時所要的花費
4、對第二點及以后的每一點進行更新。dp[i][j]第i+1點到高度j時的前i+1個總的花費
5、找到更后最后一個點到任意高度的最小值便為答案
AC代碼:
#include<string.h> #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; const int M=2e3+10; int n,k; int a[M],b[M],c[M]; int dp[M][M],e[M][M];///用數組下標進行離散化,表示某位置最小的花費 bool cmp(int x,int y) {return x>y; } int main() {cin>>n;for (int i=0; i<n; i++)cin>>a[i],b[i]=c[i]=a[i];sort(b,b+n);for (int i=0; i<n; i++)dp[0][i]=abs(b[i]-a[0]);for(int i=1; i<n; i++)//枚舉第幾座山峰{k=dp[i-1][0];for (int j=0; j<n; j++)///枚舉山峰到達離散化后某高度{k=min(k,dp[i-1][j]);dp[i][j]=k+abs(b[j]-a[i]);}}sort(c,c+n,cmp);for (int i=0; i<n; i++)e[0][i]=abs(c[i]-a[0]);for(int i=1; i<n; i++){k=e[i-1][0];for (int j=0; j<n; j++){k=min(k,e[i-1][j]);e[i][j]=k+abs(c[j]-a[i]);}}int ans=dp[n-1][0];for (int i=0; i<n; i++)ans=min(ans,min(dp[n-1][i],e[n-1][i]));cout<<ans<<endl;return 0; }總結
以上是生活随笔為你收集整理的Making the Grade POJ - 3666(离散化+dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 出汗多能减肥吗
- 下一篇: Piggy-Bank POJ - 138