挑战程序设计竞赛2.3习题:Making the Grade POJ - 3666

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

A B 1| + | A B 2| + ... + | 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


这道题据说是有一点问题的,因为它的测试数据就是求变成最小不上升的最小代价没有从大到小。
我们假设从第1个到最后一个的土地高度构成一个数组A,那么,我们可以知道,在修改后的数组B中,所有的数都属于A,因为如果过高要挖低最少须和前面一样,如果过低要拔高则最少须和前面一样,由于前面的值为A中的值,且其他情况不需要更改土地的高度,所以B中所有的值均在A中出现过。
然后我们假设dp[i][j]表示前i个土地中最大(其实也就是第i块土地的高度)是A数组从小到大排好序后第j大的数。
为什么要这样假设?本题易得 (0 ≤ Ai ≤ 1,000,000,000),如果采用传统的方法dp[i][j],i表示前i种,j表示最大的高度是j,那么算法复杂度就是O(AN)由于A最大1e9,定会超时,所以这道题解题的关键就是离散化解本题,所谓的离散化(百度百科):

离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。

通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。例如:

原数据:1,999,100000,15;处理后:1,3,4,2;

原数据:{100,200},{20,50000},{1,400};

处理后:{3,4},{2,6},{1,5};

我们把原来容易想到的j变成A数组从小到大排好序后第j大的数,因为实际上最后的所有可能都是来自于A数组中的数,这样我们就能不白白计算用不到的地方,能在规定时间完成计算。

易得递推方程dp[i][j] = min(dp[i - 1][k] + abs(a[i] - a[j])),其中(1 <= k <= j),意思就是前i个土地使得最后一个土地的值为j时,可以由前i-1块土地中最后一块土地(也就是第i-1块土地)的高度小于等于j作为跳板,把第i块土地高度变为j从而得到dp[i][j]。为了减少时间(因为每次计算min(dp[i - 1][k])也会花费O(n)复杂度,一起就是O(n3)也是就8e9也会超时,所以我们可以用一个变量去记载前j-1个的最小,然后再和第j个比较,这样就O(1)就能得到前j个最小的。

AC代码(参考思路:https://blog.csdn.net/qq_40774175/article/details/81273048):

#include <stdio.h>
#include <algorithm>
using namespace std;
const int INF = 0x3fffffff;
int a[2005];//原数组
int b[2005];//原数组排完序的数组
long long dp[2005][2005];//dp[i][j]前i个中第i块土地为j高度的最小花费
long long min_old = INF;//前 j - 1项的最小值
long long ans = INF;//答案
int main(void)
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
        b[i] = a[i];
    }
    sort(b, b + n);
    for(int i = 0; i < n; i++)
        dp[0][i] = abs(b[i] - a[0]);//一开始让第一块地值为i,所以dp[0][i]均为abs(b[i] - a[0]),b[i]:排完序第i大高度,a[0]:第一块地的初始高度
    for(int i = 1; i < n; i++)//从2块地开始(因为i从0开始)到n块地
    {
        min_old = INF;//初始化前i - 1块地的最大高度为a[0]到a[j - 1]时那一块最小
        for(int j = 0; j < n; j++)
        {
            min_old = min(min_old, dp[i - 1][j]);//前i - 1块地的最大高度为a[0]到a[j - 1]时最小的花费与前i - 1块地最大高度为a[j]时哪个花费小
            dp[i][j] = min_old + abs(b[j] - a[i]);
        }
    }
    for(int i = 0; i < n; i++)
        ans = min(ans, dp[n - 1][i]);//答案就在前n块中第n块的高度为a[i]时(因为最后一块什么高度都有可能,都满足从小到大的条件,答案只是取其中最小值)
    printf("%lld\n", ans);
    return 0;
}
        


原文地址:https://www.cnblogs.com/jacobfun/p/12240340.html

时间: 2024-08-30 04:52:33

挑战程序设计竞赛2.3习题:Making the Grade POJ - 3666的相关文章

挑战程序设计竞赛2.2习题:Stall Reservations POJ - 3190

Stall Reservations Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A..B (1 <= A <= B <= 1,000,000), which includes both times A and B. Obviously, FJ must create a

挑战程序设计竞赛2.3习题:Cheapest Palindrome POJ - 3280

Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow an electronic ID tag that the system will read as the cows pass by a scanner. Each ID tag's contents are currently a

挑战程序设计竞赛2.3习题:Cow Exhibition POJ - 2184

"Fat and docile, big and dumb, they look so stupid, they aren't muchfun..."- Cows with Guns by Dana Lyons The cows want to prove to the public that they are both smart and fun. In order to do this, Bessie has organized an exhibition that will be

挑战程序设计竞赛2.6习题:X-factor Chains POJ - 3421

Given a positive integer X, an X-factor chain of length m is a sequence of integers, 1 = X0, X1, X2, …, Xm = X satisfying Xi < Xi+1 and Xi | Xi+1 where a | b means a perfectly divides into b. Now we are interested in the maximum length of X-factor ch

挑战程序设计竞赛3.2习题:Bound Found POJ - 2566

Signals of most probably extra-terrestrial origin have been received and digitalized by The Aeronautic and Space Administration (that must be going through a defiant phase: "But I want to use feet, not meters!"). Each signal seems to come in two

挑战程序设计竞赛2.2习题:Allowance POJ - 3040

Allowance As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the

挑战程序设计竞赛2.4习题:Moo University - Financial Aid POJ - 2010

Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wishing to admit

挑战程序设计竞赛3.1习题:Moo University - Financial Aid POJ - 2010

(原题见POJ2010) 这道题我之前采用了优先队列+预处理的方法求解(https://www.cnblogs.com/jacobfun/p/12244509.html),现在用二分的办法进行求解. 一开始我很纳闷,采用二分求解本题,如果二分的mid值不符合条件,按照二分右边界应该为mid - 1(我采用前闭后闭的二分),那么如果mid + xxx(xxx大于0)可以呢?(考虑mid不行是因为左边最小加起来大了,mid ~ mid + xxx中有极小值,使得mid + xxx的左边可以满足,那么

[转] AOJ 0525 Osenbei《挑战程序设计竞赛(第2版)》练习题答案

来自 码农场 ? AOJ 0525 Osenbei<挑战程序设计竞赛(第2版)>练习题答案 只把代码复制过来,原博的其他分析请看链接. 1 #include <iostream> 2 #include <bitset> 3 #include <algorithm> 4 5 using namespace std; 6 7 bitset<10000> cookie[10]; 8 9 ///////////////////////////SubMai