欢迎光临散文网 会员登陆 & 注册

LeetCode(动态规划):464. 我能赢吗

2023-01-13 00:44 作者:嘿拜灰  | 我要投稿

关于本题中的位运算

public boolean f(int maxChoosableInteger, int desiredTotal, int choos) {
    if (desiredTotal <= 0) {
      return false;
   }
    if (dp.containsKey(choos)) {
      return dp.get(choos);
   }
    for (int i = 1;i <= maxChoosableInteger;i++) {
      if ((choos & (1 << i)) == 0) {
        if (!f(maxChoosableInteger,desiredTotal-i,choos | (1 << i))) {
          dp.put(choos,true);
          return true;
       }
     }
   }
    dp.put(choos,false);
    return false;
 }
怎么理解这个?
choos & (1 << i)) == 0 // 判断i是否被拿
choos | (1 << i)   // 将第i位bit位标为1
// 举个例子
  //假如整数池是这样
   1 2 3 4 5 6 7 8 9 10
  // 最开始打算用一个一维数组表示 可以这样
value : 0 0 0 0 0 0 0 0 0 0 0 -> int[]
index : 0 1 2 3 4 5 6 7 8 9 10 
  // 由于线性结构对于改动态规划来说复杂度较高,所有将参数int[]降维成int类型
  // 利用int32个bit位表达信息 那么可以这样
  0 0 0 0 0 0 0 0 0 0 0 -> int
  // 此时我们将0视为未拿 1视为已拿
  // 如果 9被拿了那么从右往左以0位置起始就是第9位bit位标为1
  0 1 0 0 0 0 0 0 0 0 0 -> int
  // 假如10已经被拿了但是此时想拿9怎么标 将 1左移9位并且与choos做或运算 也就是这种表达:choos | (1 << 9)
  // 由于 : 0 | 0 = 0; 0 | 1 = 1; 1 | 1 = 1;
choos: 1 0 0 0 0 0 0 0 0 0 0 -> int
help: 0 1 0 0 0 0 0 0 0 0 0 -> int
ans:  1 1 0 0 0 0 0 0 0 0 0 -> int
  // 假如10,9,7,1都被拿了如何判断9是否被拿 可以利用1左移9位并且与choos做与运算也就是这种表达:choos & (1 << 9)
  // 如果 ans != 0; 说明9已经被拿了
  // 由于 : 0 & 0 = 0; 0 & 1 = 0; 1 & 1 = 1;
choos: 1 1 0 1 0 0 0 0 0 1 0 -> int
help: 0 1 0 0 0 0 0 0 0 0 0 -> int
ans:  0 1 0 0 0 0 0 0 0 0 0 -> int



LeetCode(动态规划):464. 我能赢吗的评论 (共 条)

分享到微博请遵守国家法律