1616public class Code02_SmallestSufficientTeam {
1717
1818 public static int [] smallestSufficientTeam (String [] skills , List <List <String >> people ) {
19- Arrays .sort (skills );
2019 int n = skills .length ;
2120 int m = people .size ();
2221 HashMap <String , Integer > map = new HashMap <>();
2322 int cnt = 0 ;
2423 for (String s : skills ) {
25- if (!map .containsKey (s )) {
26- map .put (s , cnt ++);
27- }
24+ // 把所有必要技能依次编号
25+ map .put (s , cnt ++);
2826 }
27+ // arr[i] : 第i号人掌握必要技能的状况,用位信息表示
2928 int [] arr = new int [m ];
3029 for (int i = 0 , status ; i < m ; i ++) {
3130 status = 0 ;
32- for (String s : people .get (i )) {
33- if (map .containsKey (s )) {
34- status |= 1 << map .get (s );
31+ for (String skill : people .get (i )) {
32+ if (map .containsKey (skill )) {
33+ // 如果当前技能是必要的
34+ // 才设置status
35+ status |= 1 << map .get (skill );
3536 }
3637 }
3738 arr [i ] = status ;
@@ -43,28 +44,43 @@ public static int[] smallestSufficientTeam(String[] skills, List<List<String>> p
4344 int size = f (arr , m , n , 0 , 0 , dp );
4445 int [] ans = new int [size ];
4546 for (int j = 0 , i = 0 , s = 0 ; s != (1 << n ) - 1 ; i ++) {
46- if (i + 1 == m || dp [i ][s ] != dp [i + 1 ][s ]) {
47+ // s还没凑齐
48+ if (i == m - 1 || dp [i ][s ] != dp [i + 1 ][s ]) {
49+ // 当初的决策是选择了i号人
4750 ans [j ++] = i ;
4851 s |= arr [i ];
4952 }
5053 }
5154 return ans ;
5255 }
5356
57+ // arr : 每个人所掌握的必要技能的状态
58+ // m : 人的总数
59+ // n : 必要技能的数量
60+ // i : 当前来到第几号人
61+ // s : 必要技能覆盖的状态
62+ // 返回 : i....这些人,把必要技能都凑齐,至少需要几个人
5463 public static int f (int [] arr , int m , int n , int i , int s , int [][] dp ) {
5564 if (s == (1 << n ) - 1 ) {
65+ // 所有技能已经凑齐了
5666 return 0 ;
5767 }
68+ // 没凑齐
5869 if (i == m ) {
70+ // 人已经没了,技能也没凑齐
71+ // 无效
5972 return Integer .MAX_VALUE ;
6073 }
6174 if (dp [i ][s ] != -1 ) {
6275 return dp [i ][s ];
6376 }
77+ // 可能性1 : 不要i号人
6478 int p1 = f (arr , m , n , i + 1 , s , dp );
79+ // 可能性2 : 要i号人
6580 int p2 = Integer .MAX_VALUE ;
6681 int next2 = f (arr , m , n , i + 1 , s | arr [i ], dp );
6782 if (next2 != Integer .MAX_VALUE ) {
83+ // 后续有效
6884 p2 = 1 + next2 ;
6985 }
7086 int ans = Math .min (p1 , p2 );
0 commit comments