周赛5992. 基于陈述统计最多好人数

题目

游戏中存在两种角色:

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

给你一个下标从 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 个玩家的陈述,返回可以认为是 好人 的 最大 数目。

提示:

n == statements.length == statements[i].length
2 <= n <= 15
statements[i][j] 的值为 0、1 或 2
statements[i][i] == 2

思路

在leetcode上看见有人说:n<=20 的题目一般是暗示 状态压缩/二进制枚举/回溯,觉得很对,在此记录一下。
我们可以发现,0代表坏,1代表好,2无影响。因此我们只需要用0、1来表示,此时二进制思路应该扑面而来。
数组长度小于15,215也不会出现超时现象,可以进行暴力求解。因此可以将二进制每一位代表1个人的好坏,枚举所有的2n可能性(即每个人好坏的所有可能性)。
对于每一种可能性,找到该可能性中说真话的人,如果他们的判断和这种可能性不符合,则筛去。
最后所有能对应上的情况就是真实情况。

代码

class Solution {
public:
    int maximumGood(vector<vector<int>>& statements) {
       int maxx = 0;//标记最大值
       int len = statements.size();
       for(int num=0;num<(1<<len);num++){  //1<<len代表2^len+1
            int sum = 0, flag = 0; //flag标记是否是不符合现象
            //遍历数组
            for(int i=0;i<len;i++){
               if((num>>i)&1){
                   for(int j=0;j<len;j++){
                       if(statements[i][j]!=2&&statements[i][j]!=(num>>j&1)){
                           flag = 1;
                           break;
                       }
                   }
                   sum++;
               }
               if(flag) break;
            }
            //如果该情况符合,比较出最多的好人
            if(flag==0)
                maxx = max(maxx, sum);
       } 
       return maxx;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值