这题有个重要性质:

我们设 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 棋盘游戏 解题报告的更多相关文章

  1. BZOJ 2959: 长跑 解题报告

    2959: 长跑 Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑 ...

  2. BZOJ 3901 棋盘游戏 (找结论+枚举+贪心)

    题面 略 BZOJ 传送门 分析 具体分析见 dalao博客 妙就妙在当i<x,j<xi<x,j<xi<x,j<x时,(i,j)(i,j)(i,j) ^ (i,x) ...

  3. BZOJ 4238 电压 解题报告

    BZOJ 4238 电压 考虑一条边成为答案以后,删去Ta后剩下的图是一个或很多个二分图,即没有奇环 则一条边可以成为答案,当且仅当自己在所有奇环的交上且不在偶环上. 考虑建出dfs树,那么返祖边一定 ...

  4. BZOJ 3159: 决战 解题报告

    BZOJ 3159: 决战 1 sec 512MB 题意: 给你一颗\(n\)个点,初始点权为\(0\)的有跟树,要求支持 Increase x y w 将路径\(x\)到\(y\)所有点点权加上\( ...

  5. 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- ...

  6. BZOJ 4302 Buildings 解题报告

    这个题好像很有趣的样子. 题目分析: 房间都是 $1\times k$ 的,也就是一条一条的.这个好像比较显然的样子. 一个房间如果要覆盖某个格子$u$,那么这个房间的面积至少为 $dis(u, Bo ...

  7. BZOJ 3160 万径人踪灭 解题报告

    这个题感觉很神呀.将 FFT 和 Manacher 有机结合在了一起. 首先我们不管那个 “不能连续” 的条件,那么我们就可以求出有多少对字母关于某一条直线对称,然后记 $T_i$ 为关于直线 $i$ ...

  8. BZOJ 4127 Abs 解题报告

    这个题感觉很厉害的样子.. 首先我们注意到一点:每次加的 $d$ 都是非负的. 那么就说明一个数只可能从负数变成非负数并且只会变一次. 所以我们就可以暴力地去改变一个数的正负情况. 然后我们就可以用树 ...

  9. BZOJ 3953 Self-Assembly 解题报告

    首先,我们可以先考虑一个暴力一点的算法: 对于任意两个分子,如果它们能以至少一种进行匹配,那么我们就在这两个分子之间连一条边. 然后如果我们能找到一个环,就说明是 unbounded,否则就是 bou ...

随机推荐

  1. 怎样安装WIN7系统

    如何避免win7自动创建200M隐藏分区 1 安装win7到选择安装到哪个分区的时候,不能选择 unallocated diskspace ,也不能选 delete 已有的分区(例如C盘)安全的做法是 ...

  2. MATLAB的基本元素

    MALTAB程序的基本数据单元是数组,MATLAB 的变量名必须以字母开头,后面可以跟字母,数字和下划线(_).只有前31个字符是有效的:如果超过了31 个字符,基余的字符将被忽略.如果声明两个变量, ...

  3. php的递归函数

    递归函数,就是在函数体内调用自身 例子: <?php function repayment($number){  if ($number<10){   echo $number." ...

  4. HTML <input> 标签的 type 属性

    HTML <input> 标签的 type 属性 HTML <input> 标签 实例 下面的表单拥有两个输入字段以及一个提交按钮: <form action=" ...

  5. 经历:easyui的layout自适应高度布局

    在使用easyui的layout布局的时候,在某种情况下,我们会在后续的逻辑中修改一下layout的某个region的高度,那么该怎么做呢?  我就遇到了这样的情况,今天需求经理提出了一个需求:认证用 ...

  6. ajax详解,以及异步JSOP的实现

    这里我使用的是jquery的ajax方法   包括三个方法 : get() , post(),   getJson() get() 和post()的格式我就使用一下格式,很方便: $.ajax({ u ...

  7. Cannot connect to (local) sql server 2008

    Make following steps to solve the issue: Cannot connect to (local). ADDITIONAL INFORMATION: Login fa ...

  8. Struts2文件上传方式与上传失败解决方式

    首先将几个对象弄出来第一个 上传页面第二个 上传action第三个 startut2配置文件 我的文字描述不是很好,但是终归是自己写出来的,后来我在网上看到一篇关于文件上传描述的非常清楚的文章, 链接 ...

  9. Javascript中的迭代、归并方法

    迭代方法 在Javascript中迭代方法个人觉得尤为重要,在很多时候都会有实际上的需求,javascript提供了5个迭代方法来供我们操作,它们分别为: every() 对数组中的每一个项运用给定的 ...

  10. jQuery事件绑定和委托

    可以用多种方法实现,on()  . bind()  . live()  . delegate() ,还有one(). 有时我们可能会像下面这样绑定一个事件: $("#div1"). ...