解 1:爆搜+剪枝
暴力搜索很明显是枚举每一个为 .的点保留原来的状态或者变为 +,最后进行判断。时间复杂度 2 n × m × n × m 2^{n\times m}\times n\times m 2n×m×n×m,第一个测试数据就是为了能够通过这样的数据构造的。
考虑剪枝优化。如果当前的答案之后就算加上了理论的全部可以为 +的地方还是比不过原来的答案,那么就可以直接返回。
这个很像 IDA-star 中的估价函数,只不过这里的最大深度是搜过的答案。
IDA-star 是用于应对最小答案,方法是将答案估小。而这里要求的是最答案,所以应当将答案估大。比如当前答案为 3 3 3,最优答案为 5 5 5。假如当前答案扩展出来的答案更优,但是估价函数将其估小估到了 4 4 4,那就会被击毙从而导致答案可能错误。
这里可以估成之后所有点都为 +的情况,一定不会 WA。
判断是否形成环也很好弄,并查集、dfs 或者 bfs 都是可以的。这里用了 dfs(带权并查集之前写挂了,现在还在痛恨并查集。),比如走着走着走到了之前标记的点,并且不是上一个点,那就有环。
发现这里的估价函数剪枝可能优化不了时间(原理同 K 短路的 A-star 算法被卡),还需要加上一些剪枝。
比如当前节点加上去就已经是有环的了,那么就不用往后搜。这个限制了指数(虽然本人很蒻算不出最少能卡多少个不对的情况),而且 dfs 判环最多 6 × 6 = 36 6\times 6=36 6×6=36,可以当成常数,所以在大数据下不比没剪枝的代码更劣。
加上去就能够 AC 了。
#include<bits/stdc++.h>
#define MAXN 17
using namespace std;
int n,m,sx,sy,cnt,ans;
char mp[MAXN][MAXN];
char ouf[MAXN][MAXN];
char dfn[MAXN][MAXN];
bool vis[MAXN][MAXN];
int dx[4]={
0,1,0,-1};
int dy[4]={
1,0,-1

最低0.47元/天 解锁文章
1048

被折叠的 条评论
为什么被折叠?



