1601. 最多可达成的换楼请求数目
枚举法+状态压缩:
- 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. 括号生成 (状态压缩解法)
枚举法+状态压缩:
- 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. 完成所有工作的最短时间
动态规划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];
}
};