package class50; public class Problem_0600_NonnegativeIntegersWithoutConsecutiveOnes { // // f(0, false, 5,n) // // 6 5 ... 0 -1 n // // 0 ? 停 // // // 5 4 3 2 1 0 -1 // // n : 1 0 1 1 1 0 // // 0 1 i // // pre : 第i+1位做的决定,0还是1 // // 在 第i+1位做的决定 是pre的情况下,从index位开始,往后都做决定! // // 但是,不能有相邻的1,请问有多少决定!返回! // // alreadyLess : 之前的决定,是不是已经导致你到index的时候,已经比n小了! // // pre -> 0 1 // // alreadyLess -> true false // // index -> n的位数,(logN) // // 2 * 2 * logN // // dp[2][] // // int alreadyLess 0 1 // public int f(int pre, boolean alreadyLess, int index, int n) { // if (index == -1) { // return 1; // } // if (pre == 1) { // // 只能做0的决定,然后去往i-1位置 // boolean curLessOrMore = alreadyLess | ((n & 1 << index) != 0); // return f(0, curLessOrMore, index - 1, n); // } else { // pre == 0的决定 // // 可能性1,继续做0的决定 // boolean curLessOrMore = alreadyLess | ((n & 1 << index) != 0); // int p1 = f(0, curLessOrMore, index - 1, n); // // 可能性2,做1的决定 // // 1)pre == 0的决定, 2) // int p2 = 0; // if (alreadyLess || (n & 1 << index) != 0) { // p2 = f(1, alreadyLess, index - 1, n); // } // return p1 + p2; // } // } public static int findIntegers(int n) { int i = 31; for (; i >= 0; i--) { if ((n & (1 << i)) != 0) { break; } } // for循环出来之后,i表示,n最高位的1,在哪? // 从这个位置,往右边低位上走! int[][][] dp = new int[2][2][i + 1]; return f(0, 0, i, n, dp); } public static int f(int pre, int alreadyLess, int index, int num, int[][][] dp) { if (index == -1) { return 1; } if (dp[pre][alreadyLess][index] != 0) { return dp[pre][alreadyLess][index]; } int ans = 0; if (pre == 1) { ans = f(0, Math.max(alreadyLess, (num & (1 << index)) != 0 ? 1 : 0), index - 1, num, dp); } else { if ((num & (1 << index)) == 0 && alreadyLess == 0) { ans = f(0, alreadyLess, index - 1, num, dp); } else { ans = f(1, alreadyLess, index - 1, num, dp) + f(0, Math.max(alreadyLess, (num & (1 << index)) != 0 ? 1 : 0), index - 1, num, dp); } } dp[pre][alreadyLess][index] = ans; return ans; } }