Beijing Guards LA3177

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits> 
#include <set>
#include <string> 
#include <sstream>
#include <utility>
#include <ctime>
//#pragma comment(linker, "/STACK:1024000000,1024000000") 

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::getline;
using std::make_pair;
using std::greater;

const int MAXN(100010);

int gift[MAXN];
int left[2], right[2];
int n;

bool is_legal(int sum)
{
	int x = gift[1], y = sum-gift[1];
	int cur = 0, last = 1;
	left[last] = gift[1];
	right[last] = 0;
	for(int i = 2; i <= n; ++i)
	{
		if(i&1)
		{
			right[cur] = min(y-right[last], gift[i]);
			left[cur] = gift[i]-right[cur];
		}
		else
		{
			left[cur] = min(x-left[last], gift[i]);
			right[cur] = gift[i]-left[cur];
		}
		swap(cur, last);
	}
	return left[last] == 0;
}

int main()
{
	while(scanf("%d", &n), n)
	{
		int L = 0, R = 0;
		for(int i = 1; i <= n; ++i)
			scanf("%d", gift+i);
		if(n == 1)
		{
			printf("%d\n", gift[1]);
			continue;
		}
		gift[n+1] = gift[1]; 
		for(int i = 1; i <= n; ++i)
			L = max(L, gift[i]+gift[i+1]);
		if(n&1)
		{
			for(int i = 1; i <= n; ++i)
				R = max(R, gift[i]*3);
			while(L < R)
			{
				int m = (L+R) >> 1;
				if(is_legal(m))
					R = m;
				else
					L = m+1;
			}
		}
		printf("%d\n", L);
	}
	return 0;
}


你可能感兴趣的:(Beijing Guards LA3177)