Topic Links:http://lightoj.com/volume_showproblem.php?problem=1018
Test Instructions Analysis:There are no more than n points on the plane, they can now be drawn in any direction, asking: at least a few times to draw all the points?
Problem Solving Ideas:We can use the set S to indicate: what points have not been crossed off, then transfer dp[s] = Min (Dp[s & (~line[i][j])]) + 1; This involves the handling of line[i][j], which represents a number of points in a straight line consisting of I and J points, Need to be processed beforehand. The boundary condition is the set element in S >0 && <= 2 o'clock, which is definitely 1. The element is 0 when it is empty.
Personal experience:The first thought is to use s to represent the current point has not been across the set, and then stuck in the How to transfer, thinking about choosing two points to traverse the judgment of the two points in the straight line there are several points, feel fried chicken trouble. Then is to turn over the other people's solving, see the word pretreatment, suddenly enlightened ah ~
The specific code is as follows:
#include <iostream> #include <cctype> #include <cstdio> #include <cstring> #include <string > #include <cmath> #include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 20;int X[MAXN], Y[MAXN], LINE[MAXN][MAXN], N, dp[1 << 16];void init () {memset (line, 0, sizeof line); Memset (DP, 0x3f, sizeof DP); Dp[0] = 0; for (int i = 0, i < n; ++i) for (int j = i + 1; j < n; ++j) {Line[i][j] = (1 << i) | (1 << j); int dx = x[j]-x[i], dy = y[j]-y[i]; for (int k = j + 1; k < n; ++k) {int dx2 = X[k]-x[i], Dy2 = y[k]-y[i];//Here I use the vector parallel condition if (dx2 * dy = = dy2 * dx) line[i][j] |= (1 << k); } Line[j][i] = Line[i][j]; }}int DFS (int s) {int& ret = dp[s]; if (Dp[s] < INF) return ret; int num = __builtin_popcount (s); There are several 1 calculations in S. Useful function if (num <= 2) return ret = 1; int i = 0; while (!) ( S & (1 << i)) ++i; Find the first not deleted point for (int j = i + 1; j < n; ++j)//match with other points. The matching order here will not affect the final result of {if (S & (1 << j)) {ret = min (ret, DFS (s& (~line[i][j))) + 1); }} return ret;} int main () {int t; for (int kase = scanf ("%d", &t), Kase <= t; ++kase) {scanf ("%d", &n); for (int i = 0; i < n; ++i) scanf ("%d%d", X+i, Y+i); Init (); printf ("Case%d:%d\n", Kase, Dfs ((1 << N)-1)); }return 0;}
Copyright NOTICE: Welcome reprint (^ω^) ~ But reprint please indicate source: Http://blog.csdn.net/catglory? (????)
[Lightoj 1018] Brush (IV) [pressure DP]