这种分成了三个节点一般都可以处理一下前缀处理一下后缀,或者处理一下前面的这个点,处理一下后面的这个点,然后再枚举中间这个点。
如果和中间这个点有关的,那么就可以换一下顺序,先枚举中间这个点,然后处理前面和后面的点。
这个是先枚举中间这个点,然后往前面贪心,往后面贪心。
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #include <string> #include <algorithm> #include <iostream> #include <map> #include <list> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int maxn = 5e3 + 10; ll sum[maxn], a[maxn]; int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%lld", &a[i]), sum[i] = sum[i - 1] + a[i]; ll ans = 0, x = 1, y = 1, z = 1; for(int i=1;i<=n;i++) { ll res1 = 0, mark1 = 1; for (int j = i; j <= n + 1; j++) { ll num = sum[j - 1] * 2 - sum[i - 1] - sum[n]; if (num > res1) res1 = num, mark1 = j; } ll res2 = 0, mark2 = 1; for (int j = 1; j <= i; j++) { ll num = 2 * sum[j - 1] - sum[i - 1]; if (num > res2) res2 = num, mark2 = j; } if(res1+res2>ans) { ans = res1 + res2; x = mark2, y = i, z = mark1; // printf("ans=%d\n", ans); } } printf("%lld %lld %lld\n", x - 1, y - 1, z - 1); return 0; }View Code