For more information, see here.
Question: For a sequence arr [], you can select a subsequence from which the values of the subsequence are placed from left to right on the leaf node of a binary tree so that the leaves are not removed, the left and right subtree weights of all nodes are equal. The right of the subtree = the right of the subtree leaves. If such a binary tree exists, the sub-sequence selected is valid. Q: What is the longest legal subsequence.
Ideas:
The minimum weight (start point) of the leaves that may belong to an enumerated binary tree. Obviously, the number of Binary Trees that can be combined with this number is equal to this number or 2 ^ K times the number. Consider the number that satisfies this relationship as a set. Obviously, the number outside the set cannot form a binary tree with the number in the set. Then, we only need to obtain the oldest sequence of all sets one by one.
Divide all the numbers in the set by the minimum weight, and the remaining number is the number of 2 ^ K, such as 1, 2, 4, 8, 16, 32, 64. Assume that you enter 16 in the first field from left to right, and the number in the second field is not larger than 16. Otherwise, the 16 fields cannot be merged. If 16 is entered, it is combined into 32. Of course, the number smaller than 16 is also a row. Therefore, for the number of 2 ^ K, each number must have only one or no State during the merge process. Then we can use state compression.
For details, see the code:
# Include <algorithm> # include <iostream> # include <string. h> # include <stdio. h> using namespace STD; const int INF = 0x3f3f3f3f; const int maxn = 1010; typedef long ll; bool base [maxn * 505], vis [505], ISS [maxn]; int arr [maxn], DP [maxn * 505], BRR [maxn], sum [maxn]; int solve (int x, int N) {int I, j, Lim, TP, Ct = 0, ANS = 0; for (I = 1; I <= N; I ++) if (ARR [I] % x = 0 & base [arr [I]/X]) BRR [++ CT] = arr [I]/X; for (I = 1; I <= CT; I ++) sum [I] = sum [I-1] + B Rr [I]; memset (DP, 0xcf, sizeof DP); DP [0] = 0; for (I = 1; I <= CT; I ++) {Lim = 2 * BRR [I]; for (j = sum [I]; j> = lim; j --) {TP = J-Brr [I]; If (! (TP & (BRR [I]-1) DP [J] = max (DP [J], DP [TP] + 1 );} DP [BRR [I] = max (DP [BRR [I], 1) ;}for (I = 1; I <= sum [cT]; I ++) if (base [I]) ans = max (ANS, DP [I]); Return ans;} int main () {int N, I, j, Lim, ans; lim = 500 * maxn; for (I = 1; I <Lim; I <= 1) base [I] = true; while (scanf ("% d ", & N), n) {for (I = 1; I <= N; I ++) scanf ("% d", & arr [I]); memset (VIS, 0, sizeof vis); for (I = 1; I <= N; I ++) {ISS [I] = true; // whether the minimum weight of the leaf node is if (vis [arr [I]) {ISS [I] = false; continu E;} vis [arr [I] = true; For (j = 1; j <= N; j ++) {If (j = I) continue; if (ARR [I]! = Arr [J] & arr [I] % arr [J] = 0 & base [arr [I]/ARR [J]) {ISS [I] = false; break ;}} ans = 0; for (I = 1; I <= N; I ++) if (ISS [I]) ans = max (ANS, solve (ARR [I], n); printf ("% d \ n", ANS);} return 0 ;}
Uvalive 6669 hidden tree (strong pressure DP)