299

Minimum Score After Removals on a Tree

Failed this one. Learn from endlesscheng: DFS timestamp

class Solution:
    def minimumScore(self, nums: List[int], edges: List[List[int]]) -> int:
        n = len(nums)
        g = [[] for _ in range(n)]
        for x, y in edges:
            g[x].append(y)
            g[y].append(x)

        xor, in_, out, clock = [0] * n, [0] * n, [0] * n, 0
        def dfs(x: int, fa: int) -> None:
            nonlocal clock
            clock += 1
            in_[x] = clock
            xor[x] = nums[x]
            for y in g[x]:
                if y != fa:
                    dfs(y, x)
                    xor[x] ^= xor[y]
            out[x] = clock
        dfs(0, -1)
        def is_parent(x: int, y: int) -> bool:
            return in_[x] <= in_[y] <= out[x]

        for e in edges:
            if not is_parent(e[0], e[1]):
                e[0], e[1] = e[1], e[0]  # 保证 e[0] 是 e[1] 的父节点
        ans = inf
        for (x1, y1), (x2, y2) in combinations(edges, 2):
            if is_parent(y1, x2):  # y1 是 x2 的祖先节点(或重合)
                x, y, z = xor[y2], xor[y1] ^ xor[y2], xor[0] ^ xor[y1]
            elif is_parent(y2, x1):  # y2 是 x1 的祖先节点(或重合)
                x, y, z = xor[y1], xor[y2] ^ xor[y1], xor[0] ^ xor[y2]
            else:  # 删除的两条边分别属于两颗不相交的子树
                x, y, z = xor[y1], xor[y2], xor[0] ^ xor[y1] ^ xor[y2]
            ans = min(ans, max(x, y, z) - min(x, y, z))
        return ans
Maximum Score Of Spliced Array

Very good problem.


analysis

Essentially a sum + maxSumSubarray (refer: 53, endlesscheng solution)

class Solution {
    public int maximumsSplicedArray(int[] nums1, int[] nums2) {
        return Math.max(maxSubArray(nums1, nums2), maxSubArray(nums2, nums1));
    }
    
    public int maxSubArray(int[] nums1, int[] nums2) {
        int sum = 0, maxEndHere = 0, max = 0;
        for (int i = 0; i < nums1.length; ++i) {
            sum += nums1[i];
            int diff = nums2[i] - nums1[i];
            maxEndHere = Math.max(0, maxEndHere) + diff;
            max = Math.max(max, maxEndHere);
        }
        
        return sum + max;
    }
}
Count Number of Ways to Place Houses

Obvious DP, possibly 2d, not sure. "non-adjacent" problem: might be fibonacci DP. Enumerate on one side: 2, 3, 5, 8...
e.g.

   _  _  _  _

1
2 #
3    #
4        # 
5           #
6 #     # 
7 #         #
8    #      #
class Solution {
    public int countHousePlacements(int n) {
        long[] f = new long[10001];
        int i;
        f[0] = 1; f[1] = 2;
        for (i = 2; i <= n; ++i) {
            f[i] = (f[i-1] + f[i-2]) % 1000000007;
        }
        return (int) (f[n] * f[n] % 1000000007);
    }
}

This approach can be adopted in a contest, but not good to reason; it's just an expediency generated from a pattern underhood. To better understand it, let f[n] be #ways to place n houses:

  • not place n-th house, n-th house doesn't matter: f[n] = f[n-1]
  • place n-th house: f[n] = f[n-2] cuz (n-1)th house cannot be placed;
    so f[n] = f[n-1] + f[n-2]

你可能感兴趣的:(299)