1298. Maximum Candies You Can Get from Boxes

问题:

给定n个box:

  • status[i]: 1:box[i] 打开,0:box[i] 关闭
  • candies[i]: box[i]里装有的糖个数
  • keys[i]: 装有的其他box钥匙的index(数组)
  • containedBoxes[i]: 装有的其他box的index(数组)

关闭的box,只有持有钥匙key,才能打开。

打开的box,可以直接打开。

initialBoxes:表示目前手中的盒子。(不一定都可打开)

求打开所有能打开的box后,能得到多少糖。

Example 1:
Input: status = [1,0,1,0], candies = [7,5,4,100], keys = [[],[],[1],[]], containedBoxes = [[1,2],[3],[],[]], initialBoxes = [0]
Output: 16
Explanation: You will be initially given box 0. You will find 7 candies in it and boxes 1 and 2. Box 1 is closed and you don't have a key for it so you will open box 2. You will find 4 candies and a key to box 1 in box 2.
In box 1, you will find 5 candies and box 3 but you will not find a key to box 3 so box 3 will remain closed.
Total number of candies collected = 7 + 4 + 5 = 16 candy.

Example 2:
Input: status = [1,0,0,0,0,0], candies = [1,1,1,1,1,1], keys = [[1,2,3,4,5],[],[],[],[],[]], containedBoxes = [[1,2,3,4,5],[],[],[],[],[]], initialBoxes = [0]
Output: 6
Explanation: You have initially box 0. Opening it you can find boxes 1,2,3,4 and 5 and their keys. The total number of candies will be 6.

Example 3:
Input: status = [1,1,1], candies = [100,1,100], keys = [[],[0,2],[]], containedBoxes = [[],[],[]], initialBoxes = [1]
Output: 1

Example 4:
Input: status = [1], candies = [100], keys = [[]], containedBoxes = [[]], initialBoxes = []
Output: 0

Example 5:
Input: status = [1,1,1], candies = [2,3,2], keys = [[],[],[]], containedBoxes = [[],[],[]], initialBoxes = [2,1,0]
Output: 7
 

Constraints:
1 <= status.length <= 1000
status.length == candies.length == keys.length == containedBoxes.length == n
status[i] is 0 or 1.
1 <= candies[i] <= 1000
0 <= keys[i].length <= status.length
0 <= keys[i][j] < status.length
All values in keys[i] are unique.
0 <= containedBoxes[i].length <= status.length
0 <= containedBoxes[i][j] < status.length
All values in containedBoxes[i] are unique.
Each box is contained in one box at most.
0 <= initialBoxes.length <= status.length
0 <= initialBoxes[i] < status.length

  

解法:BFS

  • 状态:
    • 当前入手的箱子(未打开):GotBoxes
    • 当前手上的钥匙。
    • 当前所有箱子的开闭状态。
  • 选择:
    • 当前箱子打开后得到的箱子(状态为开)
    • 已经入手的箱子(且在本次开箱中,获得了key)

这里,BFS只是一个尝试持续,而非多种选择分叉不同情况,

因此,各个状态用已有的单独数组进行记录即可,不用将状态入队。

只需要入队当前箱子id即可。

我们规定:只有能够打开的box,才能入队,那么每次出队的箱子中的糖果都能累计。

对于已经计算过的箱子,箱子状态为打开状态&&并非此次获得的新箱子。

我们每次入队新箱子 or 还未打开的已入手箱子。则可保证每次出队的箱子都是未计算过的。

对于每次处理的箱子:

  • 拿到该箱子中的keys,来开已经入手却没打开的箱子。
    • 同时,将入手or未入手的箱子 状态都改为 open。
  • 拿到该箱子中的新箱子,
    • 如果箱子是open状态,直接入队。
    • 否则,计入已经入手的箱子。

代码参考:

 1 class Solution {
 2 public:
 3     int n;
 4     int maxCandies(vector<int>& status, vector<int>& candies, vector<vector<int>>& keys, vector<vector<int>>& containedBoxes, vector<int>& initialBoxes) {
 5         int res = 0;
 6         n = status.size();
 7         vector<bool> GotBoxes(n,false);
 8         queue<int> q;
 9         //push Start box(opened) to queue.
10         //push all box gotten to GotBoxes
11         for(int iB:initialBoxes) {
12             if(status[iB]) {
13                 q.push(iB);
14             }// else {
15                 GotBoxes[iB] = true;
16            // }
17         }
18         //queue: boxes which 'can open' next time.
19         while(!q.empty()) {
20             int cur = q.front();
21             q.pop();
22             res += candies[cur];
23             //use keys we got this time ,to open the box we got(but is closed)
24             for(int k_box:keys[cur]) {
25                 if(status[k_box]==0 && GotBoxes[k_box]) { 
26                     q.push(k_box);
27                     //boxes which we got already but closed. this time we get the key.
28                 }
29                 status[k_box] = 1;//once get the key, box status should be open.
30             }
31             for(int nextbox:containedBoxes[cur]) {
32                 if(status[nextbox]==1) {
33                     //if we get a box which we have the key before. we can open it.
34                     q.push(nextbox);
35                 } //else {
36                     GotBoxes[nextbox] = true;//get a box closed.
37                 //}
38             }
39         }
40         return res;
41     }
42 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14543483.html