• LeetCode刷题 之 状态压缩


    1601. 最多可达成的换楼请求数目

    image

    枚举法+状态压缩

    • 01 枚举每个人的要求,满足或不满足
    • 然后相当于选出一些边, 看看选出的边集,判断其是否为一些环构成
    • 这里,可以直接使用点的度(degree)来判断
    from typing import List
    class Solution:
        def maximumRequests(self, N: int, requests: List[List[int]]) -> int:
            R = len(requests)        
            ans = 0
            for mask in range(1 << R): # 2^R种可能
                degree = [0] * N
                count = 0
                for x, (u, v) in enumerate(requests):
                    if ((1 << x) & mask) > 0:
                        degree[u] -= 1
                        degree[v] += 1
                        count += 1
                if all(x == 0 for x in degree):
                    ans = max(ans, count)
            return ans
    

    22. 括号生成 (状态压缩解法)

    image

    枚举法+状态压缩

    • 01枚举括号,0表示左括号,1表示右括号,最多才2^(2n)种情况
    from bisect import bisect
    from typing import *
    class Solution:
        def isValid(self, str):
            cnt = 0
            for ch in str:
                if ch == '(':
                    cnt+=1
                else: cnt-=1
                if cnt < 0:
                    return False
            return cnt==0
    
        def generateParenthesis(self, n: int) -> List[str]:
            ans = []
            for mask in range((1<<n)-1,1<<(2*n)):
                s = ""
                for i in range(2*n):
                    if (mask&(1<<i)) > 0:
                        s += '('
                    else:
                        s += ')'
                if self.isValid(s):
                    ans.append(s)
            return ans
    

    1723. 完成所有工作的最短时间

    image

    动态规划DP+状态压缩

    • 一共有2^n种状态
    • 动态规划更新DP数组,找到最少工作时间
    class Solution {
    public:
        int minimumTimeRequired(vector<int>& jobs, int k) {
            int n=jobs.size();
            vector<int>dp(1<<n),cost(1<<n);
            for(int mask=0; mask<(1<<n); mask++) {
                dp[mask]=1e9;
                cost[mask]=0;
                for(int i=0;i<n;i++)if(mask&(1<<i))cost[mask]+=jobs[i];
            }
            dp[0]=0;
            while(k--)
                for(int mask=(1<<n)-1; mask>=0; mask--)
                    for(int sub=mask; sub; sub=(sub-1)&mask)
                        dp[mask]=min(dp[mask],max(dp[mask^sub],cost[sub]));
            return dp[(1<<n)-1];
        }
    };
    
  • 相关阅读:
    AtCoder Beginner Contest 248 赛时记录
    AtCoder Regular Contest 139 赛时记录
    Codeforces Round #783 (Div. 2) VP 记录
    退役前的遗言 or 遗产?
    Educational Codeforces Round 127 VP 记录
    AtCoder Beginner Contest 249 赛时记录
    Codeforces Round #782 (Div. 2) VP 记录
    AtCoder Regular Contest 125 补题记录
    文本相似度检查实现
    一些题(十四)
  • 原文地址:https://www.cnblogs.com/raiuny/p/16417739.html
Copyright © 2020-2023  润新知