前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 2151. 基于陈述统计最多好人数(状态压缩)

LeetCode 2151. 基于陈述统计最多好人数(状态压缩)

作者头像
Michael阿明
发布2022-03-10 18:19:31
3820
发布2022-03-10 18:19:31
举报

文章目录

1. 题目

游戏中存在两种角色:

  • 好人:该角色只说真话
  • 坏人:该角色可能说真话,也可能说假话。

给你一个下标从 0 开始的二维整数数组 statements ,大小为 n x n ,表示 n 个玩家对彼此角色的陈述。

具体来说,statements[i][j] 可以是下述值之一:

  • 0 表示 i 的陈述认为 j 是 坏人
  • 1 表示 i 的陈述认为 j 是 好人
  • 2 表示 i 没有对 j 作出陈述。

另外,玩家不会对自己进行陈述。形式上,对所有 0 <= i < n ,都有 statements[i][i] = 2

根据这 n 个玩家的陈述,返回可以认为是 好人最大 数目。

示例 1:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
输入:statements = [[2,1,2],[1,2,2],[2,0,2]]
输出:2
解释:每个人都做一条陈述。
- 0 认为 1 是好人。
- 1 认为 0 是好人。
- 2 认为 1 是坏人。
以 2 为突破点。
- 假设 2 是一个好人:
    - 基于 2 的陈述,1 是坏人。
    - 那么可以确认 1 是坏人,2 是好人。
    - 基于 1 的陈述,由于 1 是坏人,那么他在陈述时可能:
        - 说真话。在这种情况下会出现矛盾,所以假设无效。
        - 说假话。在这种情况下,0 也是坏人并且在陈述时说假话。
    - 在认为 2 是好人的情况下,这组玩家中只有一个好人。
- 假设 2 是一个坏人:
    - 基于 2 的陈述,由于 2 是坏人,那么他在陈述时可能:
        - 说真话。在这种情况下,0 和 1 都是坏人。
            - 在认为 2 是坏人但说真话的情况下,这组玩家中没有一个好人。
        - 说假话。在这种情况下,1 是好人。
            - 由于 1 是好人,0 也是好人。
            - 在认为 2 是坏人且说假话的情况下,这组玩家中有两个好人。
在最佳情况下,至多有两个好人,所以返回 2 。
注意,能得到此结论的方法不止一种。

示例 2:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
输入:statements = [[2,0],[0,2]]
输出:1
解释:每个人都做一条陈述。
- 0 认为 1 是坏人。
- 1 认为 0 是坏人。
以 0 为突破点。
- 假设 0 是一个好人:
    - 基于与 0 的陈述,1 是坏人并说假话。
    - 在认为 0 是好人的情况下,这组玩家中只有一个好人。
- 假设 0 是一个坏人:
    - 基于 0 的陈述,由于 0 是坏人,那么他在陈述时可能:
        - 说真话。在这种情况下,0 和 1 都是坏人。
            - 在认为 0 是坏人但说真话的情况下,这组玩家中没有一个好人。
        - 说假话。在这种情况下,1 是好人。
            - 在认为 0 是坏人且说假话的情况下,这组玩家中只有一个好人。
在最佳情况下,至多有一个好人,所以返回 1 。 
注意,能得到此结论的方法不止一种。
 
提示:
n == statements.length == statements[i].length
2 <= n <= 15
statements[i][j] 的值为 0、1 或 2
statements[i][i] == 2

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/maximum-good-people-based-on-statements 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • n比较小,把每个人是好人还是坏人的实际情况看成 int 的 n 位 01 二进制位
  • 枚举每种状态,遍历该状态下的好人说的话有没有矛盾的
代码语言:javascript
复制
class Solution {
public:
    int maximumGood(vector<vector<int>>& statements) {
        int n = statements.size(), ans = 0;
        for(int state = 1; state < (1<<n); ++state)
        {
            bool stop = false;
            int count = 0;
            for(int j = 0; j < n; ++j)
            { // 遍历该状态下每个人是好人还是坏人
                if((state>>j)&1) // j 是好人
                {
                    count++;
                    for(int k = 0; k < n; ++k)
                    {	// 好人说的话
                        if(statements[j][k]<2)
                        { 
                            if(statements[j][k] == ((state>>k)&1) )	// 没有矛盾
                                continue;
                            else
                            {
                                stop = true;
                                break;
                            }
                        }
                    }
                    if(stop)
                        break;
                }
            }
            if(!stop)//该状态所有好人说的话都没有矛盾
                ans = max(ans, count);
        }
        return ans;
    }
};

112 ms 8.2 MB C++


我的CSDN博客地址 https://michael.blog.csdn.net/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 题目
  • 2. 解题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档