题目描述


题目来源: HackerRank
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注
数组A包含N个元素A1, A2……AN。数组B包含N个元素B1, B2……BN。并且数组A中的每一个元素Ai,都满足1 <= Ai <= Bi。数组A的代价定义如下:

(公式表示所有两个相邻元素的差的绝对值之和)
给出数组B,计算可能的最大代价S。
Input
第1行:1个数N,表示数组的长度(1 <= N <= 50000)。
第2 - N+1行:每行1个数,对应数组元素Bi(1 <= Bi <= 10000)。
Output
输出最大代价S。
Input示例
5
10
1
10
1
10
Output示例
36


解题思想


/*
题目的意思就是Ai从1-->Bi的值求i从2-->n的Ai-Ai-1的绝对值
举个例子:假设n==2
bi 的值 为5 10
则需要求1-->5 与1-->10之间的差值的绝对值最大
如果n>2,就将所求的结果加起来即可
这里首先需要明白一点就是,差值最大则一定是取俩个线段(可以看做俩个线段)的端点做差
所以dp[i][0]就表示以第i个线段的左端点为标准,这里都为1,所取得的最大价值
dp[i][1]表示以第i个线段的右端点,这里为a[i],所取得的最大价值
所以这里决策就有俩种情况:
a 1   5
b 1   10
假设线段a,b,即为求ab之间的绝对值差值最大
首先dp[a][0] = 0 dp[a][1] = 0
应为最开始只有一个线段,所以差值为0
dp[b][0] = max(dp[a][0], dp[a][1]+abs(a[i-1]-1));
这里是以b的左端点1为标准,首先跟a的左端点比,即为dp[a][0] + (1-1)
其次再跟a的右端点比,即为dp[a][1] + abs(a[i-1]-1);
dp[a][1]就是以上个线段的那个端点取得最大值的基础上,再加上b左与a右的差值
则dp[b][1] = max(dp[a][0]+abs(a[i]-1), dp[a][i]+abs(a[i]-a[i-1])

最终再取最大值即可*/

代码


#include<iostream>
#include<cmath>
using namespace std;
const int N = 50000+10;
int dp[N][2] ,a[N];

int main()
{
    int n;
    cin >> n;
    for(int i=1; i<=n; ++i)
        cin >> a[i];
    dp[1][0] = dp[1][1] = 0;
    for(int i=2; i<=n; ++i)
    {
        dp[i][0] = max(dp[i-1][0], dp[i-1][1]+abs(a[i]-1));
        dp[i][1] = max(dp[i-1][0]+abs(a[i]-1), dp[i-1][1]+abs(a[i]-a[i-1]));
    }
    cout << max(dp[n][0], dp[n][1]) <<endl;
    return 0;
}