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(
n
2
n^{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;
}
相關文章
- POJ 2528 Mayor's posters (線段樹 區間更新+離散化)
- 離散化
- POJ 3267 The Cow Lexicon(dp)
- POJ 3071 Football(概率DP)
- 簡單dp -- Common Subsequence POJ - 1458
- POJ1390 Blocks (區間DP)BloC
- 二維座標離散化模板
- 【離散優化】覆蓋問題優化
- POJ3252Round Numbers(數位dp)
- vijos1237-隱形的翅膀【離散化】
- 離散作業
- 離散請求
- 二維字首和與差分、離散化技巧
- ECNU OJ 3353 塗黑板(線段樹離散化)
- 【DP】編輯距離
- 「暑期訓練」「基礎DP」 Common Subsequence (POJ-1458)
- 離散化的一道很經典的題
- 【scikit-learn基礎】--『預處理』之 離散化
- HDU 1542 Atlantis (線段樹+離散化+掃描線)
- BZOJ 4195 程式自動分析【並查集+離散化】並查集
- 離散數學(集合論)
- 【並查集】【離散化】[NOI2015] 程式自動分析並查集
- acm-(區間dp、迴文串、子序列)ICPC SG Preliminary Contest 2018 C - Making PalindromesACM
- 運籌優化(十四)--離散優化的啟發式演算法優化演算法
- 離散傅立葉變換
- 離散數學2 集合論
- HDU 5862 Counting Intersections(樹狀陣列+掃描線+離散化)陣列
- 線性dp:編輯距離
- [DP] DP最佳化總結
- 離散數學——4.命題邏輯公式的正規化公式
- Alink漫談(十九) :原始碼解析 之 分位點離散化Quantile原始碼
- poj--1625Censored!+AC自動機上的dp+大數
- 離散數學(數論基礎)
- 南郵離散實驗三(JAVA)Java
- OpenCV 離散傅立葉變換OpenCV
- Making Kotlin Ready for Data ScienceKotlin
- HDU 1255 覆蓋的面積(線段樹+掃描線+離散化)
- 資料處理 | pandas入門專題——離散化與one-hot