SRM549 - MagicalHats
Statement
给定 \(n\times m\) 的地图,.
表示空地,H
表示帽子,帽子下会有不超过 \(1\) 个硬币。
接下来有 numGuesses 次操作,每一次魔法师将会改变硬币的位置,然后你将选择 \(1\) 个帽子,获得的价值为帽子底下硬币的价值(如果无硬币,则价值为 \(0\))
魔法师希望你获得的价值尽可能小,而你希望尽可能大,求最后的最大价值。
Solution
观察一些性质:如果获得的硬币数为 \(x\),则价值为硬币从小到大排序后前 \(x\) 小的和。
问题进而转化为求最多能拿到多少个硬币。考虑对于 \(1\) 个帽子有几种状态:①未被掀开 ②被掀开但无硬币 ③被掀开且有硬币
所以,由于帽子数最大只有 \(13\),那么可以考虑用三进制存储下所有的状态并 DP 转移即可。
转移:
- 边界条件 \(1\):如果硬币全部放置完,则只需要判断最后的摆放是否合法即可。
- 边界条件 \(2\):如果选择次数全部使用完,则只需要判断是否存在 \(1\) 种方案放置剩余的硬币使得情况合法。
- 非边界转移:\(f_{mask}=\max(f_{mask},\min(f_{mask|i_1},f_{mask|i_2}+1))\)。这里 \(i_1\) 指第 \(i\) 个帽子被掀开但无硬币,\(i_2\) 指被掀开且有硬币。由于魔法师希望值尽可能小,所以取 \(\min\)。但是你希望尽可能取大,所以外面取 \(\max\)。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 2e6 + 10;
int n, m, tot;
PII pos[14];
int f[N];
class MagicalHats {
public:
int dp(int st, int cnt, int k) {
if (f[st] != -1) return f[st];
if (!k) {
std::vector<int> lin(n, 0), col(m, 0);
for (int i = 0; i < tot; i ++)
if ((st / (int)pow(3, i)) % 3 == 2) lin[pos[i].fi] += 2, col[pos[i].se] += 2;
else lin[pos[i].fi] ++, col[pos[i].se] ++;
for (int i = 0; i < n; i ++) if (lin[i] & 1) return f[st] = 2e9;
for (int i = 0; i < m; i ++) if (col[i] & 1) return f[st] = 2e9;
return 0;
}
if (!cnt) {
for (int i = 0; i < tot; i ++)
if ((st / (int)pow(3, i)) % 3 == 0 && dp(st + 2 * pow(3, i), 0, k - 1) == 0)
return f[st] = 0;
return f[st] = 2e9;
}
int res = 0;
for (int i = 0; i < tot; i ++)
if ((st / (int)pow(3, i)) % 3 == 0)
res = max(res, min(dp(st + pow(3, i), cnt - 1, k), dp(st + 2 * pow(3, i), cnt - 1, k - 1) + 1));
return f[st] = res;
}
int findMaximumReward(vector<string> g, vector<int> w, int turn) {
memset(f, -1, sizeof f);
n = g.size(), m = g[0].size();
for (int i = 0; i < n; i ++)
for (int j = 0; j < m; j ++)
if (g[i][j] == 'H')
pos[tot ++ ] = {i, j};
int res = dp(0, turn, w.size()), ans = 0;
if (res > w.size()) return -1;
sort(w.begin(), w.end());
for (int i = 0; i < res; i ++)
ans += w[i];
return ans;
}
};
标签:return,硬币,int,res,精讲,st,++,MagicalHats,清新
From: https://www.cnblogs.com/Tiny-konnyaku/p/18220991