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]);
}
}
结束。