0
点赞
收藏
分享

微信扫一扫

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

是波波呀 2022-03-10 阅读 28

回溯DFS

  • 路径要设成全局变量
//官方题解
class Solution {
	//delta表示每栋楼员工净变化量
	//zero表示delta中0的个数
    int[] delta;
    int ans = 0, cnt = 0, zero, n;

    public int maximumRequests(int n, int[][] requests) {
        delta = new int[n];
        zero = n;
        this.n = n;
        dfs(requests, 0);
        return ans;
    }

    public void dfs(int[][] requests, int pos) {
    	//递归结束出口
    	//枚举完毕
        if (pos == requests.length) {
        	//更新条件:所有楼的净变化量delta都为0
            if (zero == n) {
            	//满足条件则更新答案
                ans = Math.max(ans, cnt);
            }
            return;
        }

		//一、做选择
		//有两种选择
		
        //1.不选 requests[pos]
        dfs(requests, pos + 1);
        
        //2.选 requests[pos]
        int z = zero;	//为了之后能还原zero
        //二、处理选择操作
        ++cnt;
        int[] r = requests[pos];
        int x = r[0], y = r[1];
        //x离开,原来的delta[x]变化,zero怎么变
        //2-1,zero不变
        //1-0,zero++
        //0-(-1),zero--
        //可以离开前后各判断一次delta[x]===0
        zero -= delta[x] == 0 ? 1 : 0;
        --delta[x];
        zero += delta[x] == 0 ? 1 : 0;
        //到达y
        zero -= delta[y] == 0 ? 1 : 0;
        ++delta[y];
        zero += delta[y] == 0 ? 1 : 0;
        
		//三、递归下一层选择
        dfs(requests, pos + 1);

		//四、撤销选择
		//还原全局变量,因为要回溯到上一层,要似乎没有进入过下一层的选择一样
        --delta[y];
        ++delta[x];
        --cnt;
        zero = z;
    }
}

二进制枚举

思路

  • 用二进制数mask表示所有的请求
  • mask中1的个数表示已接受的请求数
  • 枚举每个mask
  • 剪枝:1的个数小于目前最多可达成的换楼请求数目,则continue
  • 对于每个mask,delta都是独立的,皆初始化为0
  • 循环已接受的请求们,更新delta
  • 更新答案 when 满足条件:delta所有值皆为0
//官方题解
class Solution {
    public int maximumRequests(int n, int[][] requests) {
        int[] delta = new int[n];
        int ans = 0, m = requests.length;
        for (int mask = 0; mask < (1 << m); ++mask) {
            int cnt = Integer.bitCount(mask);
            if (cnt <= ans) {
                continue;
            }
            Arrays.fill(delta, 0);
            for (int i = 0; i < m; ++i) {
                if ((mask & (1 << i)) != 0) {
                    ++delta[requests[i][0]];
                    --delta[requests[i][1]];
                }
            }
            boolean flag = true;
            for (int x : delta) {
                if (x != 0) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                ans = cnt;
            }
        }
        return ans;
    }
}
举报

相关推荐

0 条评论