Question: uva11008-antimatter Ray receivutting (Binary + memorizing search)
The coordinates of N trees are given. Each time a tree is cut down, the number of trees in the same straight line is given, ask how many times you need to cut to meet this requirement.
Solution: because the number of trees for this question is relatively small (16), and there are only two options: Cut and not cut, the status can be expressed using the binary number. The general idea is: select two trees that haven't been cut down in the current State each time, and cut them down together with the two trees in the same straight line, get a new status. If "= K" is returned, 0 is returned. In general, it is better to cut two trees together each time, unless there is only one tree left. Therefore, we should first pre-process the trees in the same straight line of each pair, and the State can also be expressed in binary.
Code:
# Include <cstdio> # include <cstring> const int maxn = 1 <17; const int M = 20; int DP [maxn]; int N, K; int tree [m] [2]; int line [m] [m]; bool judge (int I, Int J, int K) {int A = (tree [J] [1]-tree [I] [1]) * (tree [k] [0]-tree [J] [0]); int B = (tree [k] [1]-tree [J] [1]) * (tree [J] [0]-tree [I] [0]); return A = B? True: false;} int min (const int A, const int B) {return a <B? A: B;} void Init () {for (INT I = 0; I <n; I ++) {for (Int J = I + 1; j <N; j ++) {line [I] [J] = 0; For (int l = 0; L <n; l ++) {If (Judge (I, j, l) {line [I] [J] | = (1 <L) ;}}} for (INT I = 0; I <= (1 <n); I ++) DP [I] = m;} int count (INT s) {int ans = 0; for (INT I = 0; I <n; I ++) if (S & (1 <I) ans ++; return ans;} int dp (INT S) {Int & Ans = DP [s]; If (ANS! = M) return ans; If (count (s)> = k) return ans = 0; int flag = 0; For (INT I = 0; I <N; I ++) {If (1 <I) & S) = 0) {for (Int J = I + 1; j <n; j ++) {If (1 <j) & S) = 0) {flag = 1; ans = min (ANS, dp (S | line [I] [J]) + 1); // printf ("% d \ n", S, S | line [I] [J], ANS) ;}} if (! Flag) {ans = min (ANS, dp (S | (1 <I) + 1) ;}} return ans ;}int main () {int T; scanf ("% d", & T); For (INT I = 1; I <= T; I ++) {scanf ("% d", & N, & K); For (Int J = 0; j <n; j ++) scanf ("% d", & tree [J] [0], & tree [J] [1]); Init (); printf ("case # % d: \ n", I); printf ("% d \ n ", DP (0); if (I! = T) printf ("\ n");} return 0 ;}