您的位置:首页 > 运维架构

TopCoder SRM 672 Div2 Problem 1000 - Tdetectived2 (状压dp)

2015-10-21 13:47 471 查看

题意

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

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

思路

比赛的时候理解错题意了,以为犯罪的可能性是加上去的,实际上范围只是0~9,只不过用来维护。所以样例一直搞不过去。

dp[state]表示state状态到找到小偷状态需要多少步。

state状态里都是已经调查过的人,所以当我们拿到一个新的状态的时候维护一下这时候还没被调查过的最大的犯罪可能值,维护一下ans的最小值即可。

代码

class Tdetectived2 {
public:
vector<string> s;
int dp[1<<19], n, vis[20];

int solve(int mask, int tar)
{
int &ret = dp[mask];
if (ret != -1) return ret;
ret = INF;
int max_val = 0;
vector<int> sum(20, 0);
for (int i = 0; i < n; i++) if (mask & (1<<i))
for (int j = 0; j < n; j++) sum[j] = max(sum[j], s[i][j]-'0');
for (int i = 0; i < n; i++) if (!(mask & (1<<i)))
max_val = max(max_val, sum[i]);
for (int i = 0; i < n; i++) if (!(mask & (1<<i)) && sum[i] == max_val)
{
if (i == tar) return ret = 1;
ret = min(ret, solve(mask | (1<<i), tar)+1);
}
return ret;
}

int reveal(vector<string> _s) {
MS(vis, INF);
s = _s;
n = SZ(s);
for (int i = 1; i < n; i++)
{
MS(dp, -1);
vis[i] = solve(1, i);
}
int ans = 0;
for (int i = 1; i < n; i++) ans += i * vis[i];
return ans;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: