罪犯审问 暴力+记忆化 SRM 672 div2 1000Tdetectived2

题意

抓小偷,先从目击者0开始,选择犯罪可能性最大的一个人,如果有多人相同,选择哪个都有可能。然后更新所有人的犯罪可能性。

问如果一个人是小偷,最少几轮能被发现。

题解

暴力枚举,状态压缩DP

两重循环计算每个人的在所有人中的最大怀疑值,若等于指定人则更新答案。

int n;
vector s;
 
int memo[18][1<<18];
 
int f(int k, int mask)
{
    int & res = memo[k][mask];
    if (res == -1) {
        int susp = -1;
        int best_time = 0;
         
        // get suspicions.
        // for the maximum suspicion, remember the minimum time
        for (int i = 1; i < n; i++) {
            if ( !( (1<(su, s[j][i] - '0');
                    }
                }
                int t = 1 + ( (i == k)? 0 : f(k, mask | (1< susp) {
                    // new maximum suspicion
                    susp = su;
                    best_time = t;
                } else if ( (su == susp) && (best_time > t) ) {
                    // update minimum time
                    best_time = t;
                }
            }
        }
        res = best_time;
    }
    return res;
}
 
int reveal(vector s)
{
    // init memo table with -1s
    memset( memo, -1, sizeof(memo) );
    this->s = s;
    n = s.size();
     
    int res = 0;
     
    for (int i = 0; i < n; i++) {
        res += i * f(i, 1);
    }
    return res;
}


你可能感兴趣的:(状压DP)