本周算法总结

1.目标和

public class GoalSum {
    public static void main(String[] args) {
        System.out.println(findTargetSumWays(new int[]{1}, 1));
    }

        public static int findTargetSumWays(int[] nums, int s) {
            int sum = 0;
            for (int i = 0; i < nums.length; i++) {
                sum += nums[i];
            }
            // 绝对值范围超过了sum的绝对值范围则无法得到
            if (Math.abs(s) > Math.abs(sum)) return 0;

            int len = nums.length;
            // - 0 +
            int t = sum * 2 + 1;
            int[][] dp = new int[len][t];
            // 初始化
            if (nums[0] == 0) {
                dp[0][sum] = 2;
            } else {
                dp[0][sum + nums[0]] = 1;
                dp[0][sum - nums[0]] = 1;
            }

            for (int i = 1; i < len; i++) {
                for (int j = 0; j < t; j++) {
                    // 边界
                    int l = (j - nums[i]) >= 0 ? j - nums[i] : 0;
                    int r = (j + nums[i]) < t ? j + nums[i] : 0;
                    dp[i][j] = dp[i - 1][l] + dp[i - 1][r];
                }
            }
            return dp[len - 1][sum + s];
        }
    }

2.一和零

public class OneAndZero {
    public static void main(String[] args) {
        System.out.println(findMaxForm(new String[]{"10", "0001", "111001", "1", "0"}, 5, 3));
    }
    public static int findMaxForm(String[] strs, int m, int n) {
        int dp[][] = new int[m+1][n+1];
        for (String str : strs) {
            int one = 0,zero = 0;
            for (char c : str.toCharArray()) {
                if (c == '0')
                    zero++;
                if (c == '1')
                    one++;
            }
            for (int i = m; i >= zero; i--) {
                for (int j = n; j >= one; j--) {
                    dp[i][j] = Math.max(dp[i][j],dp[i-zero][j-one] + 1);
                }
            }
        }
        return dp[m][n];
    }

}

3.零钱兑换II

public class ChangeII {
    public static void main(String[] args) {
        System.out.println(change(5, new int[]{1,2,5}));
    }
    public static int change(int amount, int[] coins) {
        int n = coins.length;
        int[][] f = new int[n + 1][amount + 1];
        f[0][0] = 1;   // 使用0种货币,凑0元钱,也是一种方案
        for (int i = 1; i <= n; i++) {
            int v = coins[i - 1];
            for (int j = 0; j <= amount; j++)
                for (int k = 0; k * v <= j; k++)
                    f[i][j] += f[i - 1][j - k * v];  //状态计算方程
        }
        return f[n][amount];
    }
}

4.组合总和IV

public class CombinedSumIV {
    public static void main(String[] args) {
        System.out.println(combinationSum4(new int[]{1,2,3}, 4));
    }
    public static int combinationSum4(int[] nums, int t) {
        // 因为 nums[i] 最小值为 1,因此构成答案的最大长度为 target
        int len = t;
        int[][] f = new int[len + 1][t + 1];
        f[0][0] = 1;
        int ans = 0;
        for (int i = 1; i <= len; i++) {
            for (int j = 0; j <= t; j++) {
                for (int u : nums) {
                    if (j >= u) f[i][j] += f[i - 1][j - u];
                }
            }
            ans += f[i][t];
        }
        return ans;
    }
}

5.爬楼梯进阶版

public class ClimbTheStairs {
    public static void main (String[] args) {
        //dp[i] 爬到第i层阶梯 共有dp[i]种方法
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[] dp = new int[n+1];
        dp[0] = 1;
        for (int i = 1; i <= n ; i++){//背包
            for (int j = 1; j <= m; j++){//物品
                if(i >= j)
                    dp[i] += dp[i - j];
            }
        }
        System.out.print(dp[n]);
    }
}

结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值