Explorar el Código

#feat:leetcode p2787题题解

yangyi hace 2 semanas
padre
commit
1f9c3c9848
Se han modificado 1 ficheros con 95 adiciones y 0 borrados
  1. 95 0
      src/leetcode/p2787/Solution.java

+ 95 - 0
src/leetcode/p2787/Solution.java

@@ -0,0 +1,95 @@
+package leetcode.p2787;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @ProjectName: LeetCode
+ * @FileName: Solution
+ * @Author: 杨逸
+ * @Data:2025/8/12 11:48
+ * @Description: https://leetcode.cn/problems/ways-to-express-an-integer-as-sum-of-powers/description/
+ * 2787. 将一个数字表示成幂的和的方案数
+ */
+class Solution {
+    int mod = (int)1e9 + 7;
+    long f[][];
+    List<Integer> list = new ArrayList<>();
+    public int numberOfWays(int n, int x) {
+        /**
+         * 1.先算出所以可能的取值
+         * 2.然后就是选与不选的思路
+         * 问题转化为:以目标值为背包容量,以幂的值为物品的重量,求恰好装满背包的组合数
+         * 3.最后改成记忆化搜索
+         */
+        double current = 1;
+        while (true){
+            double pow = myPow(current, x);
+            if (pow > n){
+                break;
+            }
+            list.add((int)pow);
+            current++;
+        }
+        f = new long[list.size()][n+1];
+        for (int i = 0; i < f.length; i++) {
+            Arrays.fill(f[i],-1);
+        }
+        return (int)(dfs(list.size()-1,n) % mod);
+    }
+
+    private long dfs(int i, int n) {
+        //边界
+        if(i < 0){
+            return n == 0 ? 1 : 0;
+        }
+        //剪枝
+        if(n == 0){
+            return 1;
+        }
+        if(n < 0){
+            return 0;
+        }
+        //取缓存
+        if(f[i][n] != -1){
+            return f[i][n];
+        }
+        //不选
+        long res = dfs(i-1,n);
+        //能选
+        if(n>= list.get(i)){
+            res += dfs(i-1,n-list.get(i));
+        }
+        //缓存
+        return f[i][n] = res;
+    }
+
+    /**
+     * @param x 底数
+     * @param n 指数
+     * @return double
+     * @description: 快速幂
+     * @author: 杨逸
+     * @data:2025/08/12 19:11:26
+     * @since 1.0.0
+     */
+    private double myPow(double x, int n) {
+        long N = n;
+        if (N < 0){
+            //负指数的情况
+            N = -N;
+            x = 1 / x;
+        }
+        double res = 1;
+        double cur = x;
+        while(N != 0){
+            if ((N & 1) == 1){
+                res *= cur;
+            }
+            cur *= cur;
+            N >>= 1;
+        }
+        return res;
+    }
+}