最优规则式 XDU1024

来源:互联网 发布:servlet使用json 编辑:程序博客网 时间:2024/06/05 09:28

1.题目描述:点击打开链接

2.解题思路:本题要求找到四个数,满足a<b<c<d,且arr[a]+arr[d]-arr[b]-arr[c]最大。可以利用扫描法来解决。首先可以将目标式理解为两个不相交区间上的最大差值的和。那么目标就是找所有这些不想交区间最大差值的和的最大值。定义Left[i]数组维护区间[0,i)上的最大差值,Right[i]维护区间[i,n)上的最大差值。那么这两个数组不难找到如下递推式:

Left[i]=max{Left[i-1],arr[i-1]-minx};

上式中,minx是区间[0,i-1)上的最小元素。同理可得Right数组的递推式:

Right[i]=max{Right[i+1],maxx-arr[i]};

上式的maxx表示区间[i+1,n)上的最大元素。每次都可以只用O(N)的时间即可算出数组的所有值。这样,最终的答案就是max(Left[i]+Right[i])。总的时间复杂度为O(N)。

3.代码:

#define _CRT_SECURE_NO_WARNINGS #include<iostream>#include<algorithm>#include<string>#include<sstream>#include<set>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<functional>using namespace std;#define N 100000+5int a[N];int Left[N], Right[N];typedef long long ll;int main(){//freopen("t.txt", "r", stdin);int T;scanf("%d", &T);while (T--){int n;scanf("%d", &n);for (int i = 0; i < n; i++)scanf("%d", &a[i]);int ans = 0;memset(Left, 0, sizeof(Left));memset(Right, 0, sizeof(Right));Left[2] = a[1] - a[0]; int minx = min(a[0],a[1]);for (int i = 3; i <= n; i++){Left[i] = max(Left[i - 1], a[i - 1] - minx);minx = min(minx, a[i - 1]);//minx晚于Left[i]更新}Right[n - 2] = a[n - 1] - a[n - 2];int maxx = max(a[n - 1], a[n - 2]);for (int i = n - 3; i >= 0; i--){Right[i] = max(Right[i + 1], maxx - a[i]);maxx = max(maxx, a[i]);}for (int i = 2; i < n - 1; i++)ans = max(ans, Left[i] + Right[i]);printf("%d\n", ans);}return 0;}

0 0
原创粉丝点击