BZOJ 3901 棋盘游戏 解题报告
这题有个重要性质:
我们设 Flag[i][j] 表示 (i, j) 是否被奇数个操作所覆盖,
也就是操作次数对 2 取模。
设 x = (n + 1) / 2。
那么对于所有的合法的操作方案,
令 1 <= i <= x , 1 <= j < x,
都有 Flag[i][j] ^ Flag[i][x] ^ Flag[i][j + x] = 0
令 1 <= i < x , 1 <= j <= x,
都有 Flag[i][j] ^ Flag[x][j] ^ Flag[i + x][j] = 0
考虑任意一次操作,如果覆盖了 (i, x),
那么在 (i, j) 和 (i, j + x) 中必然有且仅有一个被覆盖。
(i, j) 和 (i + x, j) 同理,
于是每次都会改变那个三元组中的两个元素,或者一个都不改变。
所以这个性质也是成立的。
那么怎么说明满足上述性质的 Flag[][] 就可以对应一个合法的方案呢?
我们考虑:
我们无论怎样在这个满足性质的 Flag[][] 基础上进行操作,
这个 Flag[][] 还会是满足性质的。
先不考虑其他格子的 Flag[][] 值,
我们考虑所有的 1 <= i <= x,1 <= j <= x:
我们都可以把 Flag[i][j] 变成 0。
然后我们考虑对于所有的 1 <= i <= x,x < j <= n:
Flag[i][j] = Flag[i][x] ^ Flag[i][j - x] = 0 ^ 0 = 0
同理,其他格子的 Flag[][] 值也都会是 0。
于是满足上述性质的 Flag[][] 就可以对应一个合法的方案。
好了,那么我们就暴力枚举 Flag[x][1] - Flag[x][x] 的值,
然后 Flag[x][x + 1] - Flag[x][n] 的值也就可以确定了,
其次再分别枚举 Flag[1][x] - Flag[x - 1][x] 的值,
(这里是指一个一个处理这些值,不用再 dfs 了)
那么 Flag[x + 1][x] - Flag[n][x] 的值也可以确定了。
在此基础上对于 1 < i < x,1 < j < x:
我们可以枚举 Flag[i][j] 的值,
那么 Flag[i + x][j], Flag[i][j + x], Flag[i + x][j + x] 的值都可以确定,
于是取最优值即可。
复杂度 O(1.4^n * n^2)。
毕竟 Gromah 太弱,只会做水题。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 33 + 5
#define INF 0x7fffffff int n, x, Max, A[N][N];
bool Flag[N][N]; inline int get(int u)
{
return u == ? - : ;
} inline int Calc()
{
for (int i = x + ; i <= n; i ++)
Flag[i][x] = Flag[x][x] ^ Flag[i - x][x];
int res = ;
for (int i = ; i <= n; i ++)
res += get(Flag[i][x]) * A[i][x];
for (int i = ; i < x; i ++)
{
int _Max = -INF, sum;
for (int k = ; k < ; k ++)
{
Flag[x][i] = k;
Flag[x][i + x] = Flag[x][i] ^ Flag[x][x];
sum = get(Flag[x][i]) * A[x][i] + get(Flag[x][i + x]) * A[x][i + x];
for (int j = ; j < x; j ++)
{
int _res = -INF;
for (int _k = ; _k < ; _k ++)
{
Flag[j][i] = _k;
Flag[j][i + x] = Flag[j][i] ^ Flag[j][x];
Flag[j + x][i] = Flag[j][i] ^ Flag[x][i];
Flag[j + x][i + x] = Flag[j + x][i] ^ Flag[j + x][x];
int _sum = get(Flag[j][i]) * A[j][i] + get(Flag[j][i + x]) * A[j][i + x];
_sum += get(Flag[j + x][i]) * A[j + x][i] + get(Flag[j + x][i + x]) * A[j + x][i + x];
_res = max(_res, _sum);
}
sum += _res;
}
_Max = max(_Max, sum);
}
res += _Max;
}
return res;
} inline void dfs(int z)
{
if (z > x)
{
Max = max(Max, Calc());
return ;
}
Flag[z][x] = ;
dfs(z + );
Flag[z][x] = ;
dfs(z + );
} int main()
{
#ifndef ONLINE_JUDGE
freopen("3901.in", "r", stdin);
freopen("3901.out", "w", stdout);
#endif scanf("%d", &n);
x = n + >> ;
for (int i = ; i <= n; i ++)
for (int j = ; j <= n; j ++)
scanf("%d", A[i] + j);
dfs();
printf("%d\n", Max); #ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return ;
}
BZOJ 3901 棋盘游戏 解题报告的更多相关文章
- BZOJ 2959: 长跑 解题报告
2959: 长跑 Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑 ...
- BZOJ 3901 棋盘游戏 (找结论+枚举+贪心)
题面 略 BZOJ 传送门 分析 具体分析见 dalao博客 妙就妙在当i<x,j<xi<x,j<xi<x,j<x时,(i,j)(i,j)(i,j) ^ (i,x) ...
- BZOJ 4238 电压 解题报告
BZOJ 4238 电压 考虑一条边成为答案以后,删去Ta后剩下的图是一个或很多个二分图,即没有奇环 则一条边可以成为答案,当且仅当自己在所有奇环的交上且不在偶环上. 考虑建出dfs树,那么返祖边一定 ...
- BZOJ 3159: 决战 解题报告
BZOJ 3159: 决战 1 sec 512MB 题意: 给你一颗\(n\)个点,初始点权为\(0\)的有跟树,要求支持 Increase x y w 将路径\(x\)到\(y\)所有点点权加上\( ...
- BZOJ 3328: PYXFIB 解题报告
BZOJ 3328: PYXFIB 题意 给定\(n,p,k(1\le n\le 10^{18},1\le k\le 20000,1\le p\le 10^9,p \ is \ prime,k|(p- ...
- BZOJ 4302 Buildings 解题报告
这个题好像很有趣的样子. 题目分析: 房间都是 $1\times k$ 的,也就是一条一条的.这个好像比较显然的样子. 一个房间如果要覆盖某个格子$u$,那么这个房间的面积至少为 $dis(u, Bo ...
- BZOJ 3160 万径人踪灭 解题报告
这个题感觉很神呀.将 FFT 和 Manacher 有机结合在了一起. 首先我们不管那个 “不能连续” 的条件,那么我们就可以求出有多少对字母关于某一条直线对称,然后记 $T_i$ 为关于直线 $i$ ...
- BZOJ 4127 Abs 解题报告
这个题感觉很厉害的样子.. 首先我们注意到一点:每次加的 $d$ 都是非负的. 那么就说明一个数只可能从负数变成非负数并且只会变一次. 所以我们就可以暴力地去改变一个数的正负情况. 然后我们就可以用树 ...
- BZOJ 3953 Self-Assembly 解题报告
首先,我们可以先考虑一个暴力一点的算法: 对于任意两个分子,如果它们能以至少一种进行匹配,那么我们就在这两个分子之间连一条边. 然后如果我们能找到一个环,就说明是 unbounded,否则就是 bou ...
随机推荐
- Tomcat服务器启动常见问题
参考:http://www.cnblogs.com/xdp-gacl/p/3729033.html 学习web开发,需要先安装一台web服务器,然后再在web服务器中开发相应的web资源,供用户使用浏 ...
- uva - 10833 Supermean(二项式系数,对指数)
模拟发现,每个元素求和时,元素的系数是二项式系数,于是ans=sum(C(n-1,i)*a[i]/2^(n-1)),但是n太大,直接求会溢出,其实double的范围还是挺大的,所以可以将组合数转化成对 ...
- 亲测 asp.net 调用 webservice返回json
前端脚本 $("#sure").click(function () { var tbody = $("#putsigal tbody"); var trs = ...
- 正则表达式 自学笔记整理记录 EASY REGEX~
整理正则表达式篇 -wuian7yulian 基础知识介绍 : 1> 字符串的组成: 对于字符串"ABC"来说,其包 ...
- Java中startWith方法的使用!
今天看Java代码时,看到了字符串有一个方法是startsWith(String str)当时觉得见名之意,很简单吗,然后就自己动手做了一下,没想到发现了一个startsWith()方法的重载,sta ...
- WindowManage与Window的在Activity的一点小应用
super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN ...
- java取随机数
一, 指定的特定几个数据集合里按“随机顺序”全部取出 一碰到随机, 可能第一个想到的是用Math.Random() 来处理, 其实java本身提供了现成的类 通过 “打乱顺序”来处理“随机”问题 方法 ...
- 用pelican搭建完美博客
前面有文章介绍本站采用了Python编写的Pelican静态生成博客系统, 之所以没有使用当前很火的Jekyll, 是因为它是Ruby编写, 而我又对Ruby没有啥兴趣, 所以还是选择了使用了我熟悉的 ...
- 检测PC端和移动端的方法总结
正在苦逼的实习中,昨天公司让做一个页面,涉及到检测终端的问题,如果是手机设备,就跳转到指定的网页上,以前写响应式布局只要用@media screen来实现布局的差异化适应,但是现在不仅仅是布局,还要针 ...
- activemq spring 配置
Apache ActiveMQ是最流行和最强大的开源消息集成模式服务器.Apache ActiveMQ是速度快,支持多跨语言的客户端和协议,带有易于使用企业集成模式和许多先进的功能在充分支持JMS 1 ...