算法--2023.1.15
1.力扣198--打家劫舍
class Solution {
public int rob(int[] nums) {
int n = nums.length;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = nums[0];
//状态转移:
//遍历到第i个节点,比较遍历到前一个节点与前两个节点加上当前节点的最大值,最为第i个节点的值
for(int i = 2;i<=n;i++){
dp[i] = Math.max(nums[i-1]+dp[i-2],dp[i-1]);
}
return dp[n];
}
}
2.力扣213--打家劫舍2
class Solution {
public int rob(int[] nums) {
int n = nums.length;
if(n == 1){
return nums[0];
}
//原理同上,在此基础上,增加一个dp数组
int[] dp1 = new int[n+1];
//第二个dp数组遍历到第一个节点的时候,dp[1]设置为0代表不用低一个节点的值,这样就一定可以用最后一个节点
int[] dp2 = new int[n+1];
dp1[0] = 0;dp1[1] = nums[0];
dp2[0] = 0;dp2[1] = 0;
for(int i = 2; i<= n;i++){
dp1[i] = Math.max(dp1[i-2]+nums[i-1],dp1[i-1]);
dp2[i] = Math.max(dp2[i-2]+nums[i-1],dp2[i-1]);
}
//返回的时候,比较dp1倒数第二个节点与dp2的最后一个节点
//两种情况:
//1.如果没用到第一个节点的值,则dp2[n]>dp1[n-1];
//1.如果在dp1中用到了第一个节点的值,dp2可以保证一定没有用到,则比较dp1[n-1]与dp2[n]的值即可
return Math.max(dp1[n-1],dp2[n]);
}
}
3.力扣337--打家劫舍3
class Solution {
//树形dp问题,考虑一个节点的动态规划即可。
public int rob(TreeNode root) {
int[] temp =dfs(root);
return Math.max(temp[0],temp[1]);
}
int[] dfs(TreeNode root){
if(root == null){
return new int[]{0,0};
}
//采用后续遍历的方法进行遍历
//每次返回值是两个值,用数组保存,第一个值代表不包含当前节点值的最大值,第二个值表示可能会包含当前节点
int[] x = dfs(root.left);
int[] y = dfs(root.right);
//根结点的逻辑
//1.第一个值就是左右子节点中分别返回的最大值相加
//2.第二个值不能包含左右子节点,所以是左右叶子节点的第一个值相加
return new int[]{Math.max(x[0],x[1]) + Math.max(y[0],y[1]), x[0] + y[0] + root.val};
}
}
4.acwing285--没有上司的舞会
import java.util.Scanner;
public class acwing285 {
public static int n;
public static int[] h,e,ne;
public static int idx;
public static int[] happyValue;
public static boolean[] hasFather;
public static int[][] f;
//建立树或者图,插入边的固定方法,若只建立单链表,只记录头节点h即可不需要数组
//e[]存子节点的坐标,h[]存父节点第一个节点的坐标,每个节点具体的值用happyValue[]存
public static void add(int a, int b){
e[idx] = b; ne[idx] = h[a]; h[a] = idx++;
}
//树的动态规划
public static void dfs(int u){
f[u][1] = happyValue[u];
for(int i = h[u];i!=0;i = ne[i]){
int j = e[i];
dfs(j);
f[u][1] += f[j][0];
f[u][0] += Math.max(f[j][0],f[j][1]);
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
happyValue = new int[n+1];
h = new int[n+1]; e = new int[n+1]; ne = new int[n+1];
f = new int[n+1][2];
hasFather = new boolean[n+1];
for(int i = 1;i<=n;i++){
happyValue[i] = in.nextInt();
}
for(int i = 0;i<n-1;i++){
int a = in.nextInt(), b = in.nextInt();
add(b,a);
hasFather[a] = true;
}
int root = 1;
while(hasFather[root]){
root++;
}
dfs(root);
System.out.println(Math.max(f[root][0],f[root][1]));
}
}
理想主义的花终将在现实中绽放

浙公网安备 33010602011771号