jzxx2739Lights Out

题目描述
Farmer John has installed a fancy new milking machine in his barn, but it draws
so much power that it occasionally causes the power to go out! This happens so
often that Bessie has memorized a map of the barn, making it easier for her to
find the exit of the barn in the dark. She is curious though about the impact
of power loss on her ability to exit the barn quickly. For example, she wonders
how much farther she might need to walk find the exit in the dark.
The barn is described by a simple (non self-intersecting) polygon with integer
vertices (x_1, y_1) … (x_n, y_n) listed in clockwise order. Its edges
alternate between horizontal (parallel to the x-axis) and vertical (parallel to
the y-axis); the first edge can be of either type. The exit is located at
(x_1, y_1). Bessie starts inside the barn located at some vertex
(x_i, y_i) for i > 1. She can walk only around the perimeter of the barn,
either clockwise or counterclockwise, potentially changing direction any time
she reaches a vertex. Her goal is to travel a minimum distance to reach the
exit. This is relatively easy to do with the lights on, of course, since she
will travel either clockwise or counterclockwise from her current location to
the exit – whichever direction is shorter.
One day, the lights go out, causing Bessie to panic and forget
which vertex she is standing at. Fortunately, she still remembers the
exact map of the barn, so she can possibly figure out her position by
walking around and using her sense of touch. Whenever she is standing
at a vertex (including at her initial vertex), she can feel whether it
is a left turn or a right turn, and she can tell if that vertex is the
exit. When she walks along an edge of the barn, she can determine the
exact length of the edge after walking along the entire edge. In
general, Bessie will strategically feel her way around her starting
vertex until she knows enough information to determine where she is,
at which point she can easily figure out how to get to the exit by
traveling a minimum amount of remaining distance.
Please help Bessie determine the smallest possible amount by which
her travel distance will increase in the worst case (over all
possibilities for her starting vertex) for travel in the dark versus
in a lit barn, assuming she moves according to an optimal strategy in
each case. An “optimal” strategy for the unlit case is one that
minimizes this extra worst-case amount.

输入
The first line of the input contains N (4 <= N <= 200). Each of the
next N lines contains two integers, describing the points (x_i, y_i) in
clockwise order around the barn. These integers are in the range
-100,000 … 100,000.

输出
Please output the smallest possible worst-case amount by which
Bessie’s optimal distance in the dark is longer than her optimal
distance in a lit barn, where the worst case is taken over all
possible vertices at which Bessie can start.

样例
输入
4
0 0
0 10
1 10
1 0

输出
2

提示
In this example, Bessie can feel that she is initially standing at an inward bend, however since in this example all corners are inward bends this tells her little information.
One optimal strategy is to just travel clockwise. This is optimal is she starts at vertex 3 or 4 and only adds 2 units of distance if she starts at vertex 2.

来源/分类
USACO 2016 January Platinum

传送门

满分代码:
#include 
#include 
#include 
using namespace std;
#define MAXN 210
#define INF 0x3FFFFFFF
int opt[MAXN];
int psum[MAXN];
int canon[MAXN*2][MAXN*2];
vector<int> lparents[MAXN][MAXN];
vector<int> rparents[MAXN][MAXN];
int dp[MAXN][MAXN][MAXN][2];
int main() {
	int N;
	cin >> N;
	vector<pair<long long, long long> > A(N);
	for (int i = 0; i < N; i++) {
		cin >> A[i].first >> A[i].second;
	}
	vector<int> S(1, 0);
	for (int i = 0; i < N; i++) {
		int j = (i + 1) % N;
		int k = (i + 2) % N;
		S.push_back(abs(A[i].first - A[j].first) +abs(A[i].second - A[j].second));
		if ((A[i].first - A[j].first) * (A[k].second - A[j].second) - (A[k].first - A[j].first) * (A[i].second - A[j].second) > 0) {
			S.push_back(-1);
		} else {
			S.push_back(-2);
		}
	}
	S.back() = 0;
	for (int i = 0; i < N; i++) {
		psum[i + 1] = opt[i + 1] = opt[i] + S[2 * i + 1];
	}
	opt[N] = 0;
	for (int i = N - 1; i >= 0; i--) {
		opt[i] = min(opt[i], opt[i + 1] + S[2 * i + 1]);
	}
	for (int ln = 1; ln <= S.size(); ln++) {
		for (int i = 0; i + ln <= S.size(); i++) {
			for (int& j = canon[i][ln]; j < i; j++) {
				if (canon[j][ln - 1] == canon[i][ln - 1] && S[j + ln - 1] == S[i + ln - 1]) {
					break;
				}
			}
		}
	}
	for (int i = 0; i < S.size(); i += 2) {
		for (int ln = 3; i + ln <= S.size(); ln += 2) {
			if (i != canon[i][ln]) {
				continue;
			}
			lparents[canon[i + 2][ln - 2] / 2][ln / 2].push_back(i / 2);
			rparents[canon[i][ln - 2] / 2][ln / 2].push_back(i / 2);
		}
	}
	int result = 0;
	for (int ln = N; ln >= 1; ln--) {
		for (int i = 0; i + ln <= N + 1; i++) {
			if (canon[2 * i][2 * ln - 1] != 2 * i) {
				continue;
			}
			int dist_across = psum[i + ln - 1] - psum[i];
			for (int strt = 0; strt < ln; strt++) {
				for (int side = 0; side < 2; side++) {
					if (i == 0 || i + ln == N + 1) {
						dp[i][ln][strt][side] = -opt[i + strt];
						continue;
					}
					int lft_cst = -INF;
					vector<int>::iterator it;
					for(it=lparents[i][ln].begin(); it!=lparents[i][ln].end(); it++) {
						lft_cst = max(lft_cst, S[2 * (*it) + 1] + dp[(*it)][ln + 1][strt + 1][0]);
					}
					int rht_cst = -INF;
					for(it= rparents[i][ln].begin(); it!=rparents[i][ln].end(); it++) {
						rht_cst = max(rht_cst,S[2 * ((*it) + ln) - 1] + dp[(*it)][ln + 1][strt][1]);
					}
					(side ? lft_cst : rht_cst) += dist_across;
					dp[i][ln][strt][side] = min(lft_cst, rht_cst);
					if (ln == 1) {
						result = max(result, dp[i][ln][strt][side]);
					}
				}
			}
		}
	}
	cout << result << endl;
	return 0;
}

你可能感兴趣的:(c++,jzxx,c++,USACO)