0
点赞
收藏
分享

微信扫一扫

POJ3666 Making the Grade [DP,离散化思想]

罗蓁蓁 2023-02-08 阅读 52


Making the Grade

Time Limit: 1000MS

 

Memory Limit: 65536K

Total Submissions: 11019

 

Accepted: 5110

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


Source

​​USACO 2008 February Gold​​

 

题意:

给出长度为n的整数数列,每次可以将一个数加1或者减1,最少要多少次可以将其变成单调增或者单调减(不严格).

分析:

先说,此题数据水,光将其变成递增的就能A。


对前i个序列,构成的最优解其实就是与两个参数有关。一个是这个序列处理后的最大值mx,另一个是这个序列处理的代价值cost。

显然最大值mx最小最好(1.这样第i+1个值可以不花代价直接接在其后面的可能性更大),cost最小也最好(题意要求)。

dp[i][j]表示:前i个数构成的序列,这个序列最大值为j,dp[i][j]的值代表相应的cost(注意这里要把末尾变成j,根据1)。
 状态转移方程:  dp[i][j] =min{dp[i-1][1...j]} + abs(j - a[i])   

但j过于大,会爆内存而且还会TLE,我们用b[i]保存升序的a[i](因为我们知道我们前i个数,最优:改变后的最大值为原本的最大值),实现他的按值查找,与其一一对应

dp[i][j]表示:前i个数构成的序列,这个序列最大值为b[j],dp[i][j]的值代表相应的cost(注意这里要把末尾变成b[j],根据1)。
 状态转移方程:  dp[i][j] =min{dp[i-1][1...j]} + abs(b[j] - a[i])   

#include<cstdio>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<functional>
#include<cstring>
#include<string>
#include<cstdlib>
#include<iomanip>
#include<numeric>
#include<cctype>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<list>
#include<set>
#include<map>
using namespace std;
const int N=2005;
typedef long long ll;
ll dp[N][N];
ll a[N],b[N];
int main()
{
int n,i,j;
while(scanf("%d",&n)!=EOF)
{
for(i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
ll minn;

for(int i=1;i<=n;i++)
{
minn=1ll<<60;
for(int j=1;j<=n;j++)
{
minn=min(dp[i-1][j],minn);
dp[i][j]=minn+llabs(a[i]-b[j]);
}
}
ll ans=1ll<<60;
for(int i=1;i<=n;i++)
ans=min(ans,dp[n][i]);
printf("%lld\n",ans);
}
return 0;
}

 

举报

相关推荐

0 条评论