分治法
分治法求最大子序列和:
def calc(a, l, r): m = (l + r) >> 1 if l == r: return a[l] leftsum = calc(a, l, m) rightsum = calc(a, m + 1, r) thissum = 0 rightbordersum = 0 leftbordersum = 0 for i in range(m + 1, r + 1): thissum += a[i] rightbordersum = max(rightbordersum, thissum) thissum = 0 for i in range(m, l - 1, -1): thissum += a[i] leftbordersum = max(leftbordersum, thissum) midsum = rightbordersum + leftbordersum return max(midsum, max(leftsum, rightsum)) n = eval(input()) a = list(map(int, input().split())) res = calc(a, 0, n - 1) print(res)
分治法求解凸包问题:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 7; pair<int, int> a[maxn]; pair<int, int> p[maxn]; int vis[maxn], used[maxn]; bool cmp(pair<int, int> a, pair<int, int> b) { if (a.first == b.first) return a.second < b.second; return a.first < b.first; } int calc(pair<int, int> a, pair<int, int> b, pair<int, int> c) { return a.first * b.second + c.first * a.second + b.first * c.second - c.first * b.second - b.first * a.second - a.first * c.second; } void dfs(int start, int last) { int id = -1, maxval = 0; if (start < last) { for (int i = start + 1; i < last; i++) { int temp = calc(a[start], a[i], a[last]); if (!temp) vis[i] = 1; if (temp > maxval) { maxval = temp; id = i; } } } else { for (int i = last - 1; i > start; i--) { int temp = calc(a[start], a[i], a[last]); if (!temp) vis[i] = 1; if (temp > maxval) { maxval = temp; id = i; } } } if (id != -1) { vis[id] = 1; dfs(start, id); dfs(id, last); } } int main() { int n, cnt = 0; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i].first >> a[i].second; } sort(a + 1, a + 1 + n, cmp); vis[1] = 1; vis[n] = 1; dfs(1, n); dfs(n, 1); for (int i = 1; i <= n; i++) { if (vis[i]) p[++cnt] = a[i]; } used[1] = used[cnt] = 1; cout << p[1].first << " " << p[1].second << endl; for (int i = 2; i < cnt; i++) { int temp = calc(p[1], p[cnt], p[i]); if (temp >= 0) { cout << p[i].first << " " << p[i].second << endl; used[i] = 1; } } cout << p[cnt].first << " " << p[cnt].second << endl; for (int i = 2; i < cnt; i++) { int temp = calc(p[1], p[cnt], p[i]); if (temp < 0 && !used[i]) { cout << p[i].first << " " << p[i].second << endl; used[i] = 1; } } return 0; }