bzoj 1863 二分+dp check
思路:二分之后用dp去check就好啦。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define ull unsigned long long using namespace std; const int N = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; int n, a[N], mx[N], mn[N]; bool check(int x) { if(a[1] > x) return false; mx[1] = mn[1] = a[1]; for(int i = 2; i < n; i++) { if(x - a[i-1] < a[i]) return false; mx[i] = min(a[1]-mn[i-1], a[i]); if(x-a[i-1]-a[1]+mx[i-1] >= a[i]) mn[i] = 0; else mn[i] = a[i] - (x-a[i-1]-a[1]+mx[i-1]); } int cnt = a[1] + a[n-1] - mx[n-1]; return x - cnt >= a[n]; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); if(n == 1) printf("%d\n", a[1]); else if(n == 2) printf("%d\n", a[1]+a[2]); else { int l = 1, r = 300000, ans = 300000; while(l <= r) { int mid = l + r >> 1; if(check(mid)) r = mid - 1, ans = mid; else l = mid + 1; } printf("%d\n", ans); } return 0; } /* */