您的位置:首页 > 其它

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

2015-11-07 17:04 351 查看
题意
抓小偷,先从目击者0开始,选择犯罪可能性最大的一个人,如果有多人相同,选择哪个都有可能。然后更新所有人的犯罪可能性。

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

题解
暴力枚举,状态压缩DP

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

int n;
vector<string> 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<<i) & mask) ) {
int su = 0;
for (int j = 0; j < n; j++) {
if ( (1<<j) & mask) {
su = std::max<int>(su, s[j][i] - '0');
}
}
int t = 1 + ( (i == k)? 0 : f(k, mask | (1<<i) ) );
if (su > 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<string> 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: