AtCoder ABC 301 复盘
A Overall Winner
B Fill the Gaps
C AtCoder Cards
这是一道贪心。先统计字符出现的个数,然后尝试用出现次数最少的字符的卡片去替换 @。这个策略可以被证明是正确的。
D Bitmask
第一眼看到这道题,我就想暴力枚举,直到我看见了这个:
$$1\leq N\leq 10^{18}$$
于是我们想到了如下思路:
如果把 $S$ 中的每个 ? 都改成 0,答案就是 -1。否则,你可以对每一个被改为 0 的数字从高位到低位做这样的运算:如果将该数字改为 1 不会使数字超过 $N$,则将其改为 1。
这是正确的,时间复杂度 $O(\text{字符串}\ S\ \text{的长度})$。
E Pac-Takahashi
看到
At most $18$ pairs $(i,j)$ satisfy $A_{i,j}=$
o.
我就想到了暴搜状压 DP。
这里我们先跑 $m$ 遍 $O(n)$ 的 BFS 求出从每个糖果出发到每个点的最短路。然后开逝!
- 
初始化。初始状态为 $dp_{i,j}=$ INF,$dp_{2^i,i}=d_{i,sx,sy}\ (0\leq i\leq m)$,这里 $m$ 指糖果的个数,$(sx,sy)$ 指出发点,$d_{i,j,k}$ 指从第 $i$ 个糖果出发至 $(sx,sy)$ 的最短距离。 
- 
转移。转移方程如下: 
for(int s = 1; s < (1 << m); ++s) for(int k = 0; k < m; ++k) if(dp[s][k] != 0x3f3f3f3f) for(int nx = 0; nx < m; ++nx) { if(s >> nx & 1) continue; dp[s | 1 << nx][nx] = min(dp[s | 1 << nx][nx], dp[s][k] + d[k][ls[nx].first][ls[nx].second]); }
($\LaTeX$ 太难写了,直接贴代码)
- 求解。如下:
bfs(sx, sy); if(dis[gi][gj] <= T) ans = 0; for(int s = 1; s < (1 << m); ++s) for(int k = 0; k < m; ++k) if(dp[s][k] + d[k][gi][gj] <= T) { int now = 0; for(int i = 0; i < m; ++i) if(s >> i & 1) ++now; ans = max(ans, now); }

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号