FJUT Home_W的拆分序列(DP)题解

Problem Description

Home 现在给你一个序列要求你将这个序列拆成恰好两个子序列。且使得两个子序列的抖动系数之和最大。

对于一个序列c1,c2,c3,……cm. 其抖动系数=|c1-c2|+|c2-c3|+……+|cm-1-cm|

Input

单组数据,一个行是一个整数n.代表序列长度。

接下一行来有n个整数,a1,a2,a3,……an 代表这个序列

2<=n<=1000

1<=ai<=1e6

Output

输出一行代表在最优的拆分方案下,最大的抖动系数之和。注意其中任意一个子序列都不可以为空

 

思路:我们把dp[i][j]视为以i和j结尾的两列的最大值。

我们在放a[i]的时候可以放在i - 1后面,这时就是i和j结尾;或者放在i - 1前的任意一个位置j后面,这时就是i - 1和i结尾,特别的,当i是第一个数时加0。

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
#define P pair<int,int>
typedef long long ll;
using namespace std;
const int maxn = 1000 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int dp[maxn][maxn]; //以i和j结尾的最大值
int a[maxn];
int main(){
    int n;
    scanf("%d" ,&n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for(int i = 2; i <= n; i++){
        for(int j = 0; j < i - 1; j++){
            a[0] = a[i];
            dp[i][j] = max(dp[i][j], dp[i - 1][j] + abs(a[i] - a[i - 1]));
            dp[i][i - 1] = max(dp[i][i - 1], dp[i - 1][j] + abs(a[i] - a[j]));
        }
    }
    int ans = 0;
    for(int i = 1; i < n; i++)
        ans = max(ans, dp[n][i]);
    printf("%d\n", ans);
    return 0;
}

 

posted @ 2019-03-17 22:01  KirinSB  阅读(166)  评论(0编辑  收藏  举报