2019年第一篇文章 (。・∀・)ノ゙

Problem

bzoj无良权限题,拿学长的号交的

题目概要:给定一个\(n\times n\)的矩阵。令\(x=\frac {n+1}2\)。可以进行任意次以下操作:选择一个\(x\times x\)的子矩阵,将其中所有数乘上\(-1\)。求操作后矩阵元素和的最大值。\(n\leq 33\)且为奇数

Solution

这道题挺有意思的,两道题的思想一拼就成另外一道题了,而且毫不让人厌烦

发现数据范围十分有意思\(n\leq 33\),这个复杂度不是搜索就是折半搜索(废话)

其实更有意思的是\(x=\frac {n+1}2\),由于\(n\)为奇数,则\(2x=n+1\),画个图可以发现在这个棋盘里任意选两个\(x\times x\)的子矩形一定会有相交

画个图发现把子矩形移到四个角后会夹出来一个十字(就是第\(x\)行与第\(x\)列),考虑这个十字有特殊的意义

然后经过缜da密dan思cai考xiang发现这个十字是有对称的意义在里头的,也就是说\(a[1][i],a[1][x],a[1][i+x]\)的选择状态是有关联的,关联就是他们的选择状态的异或和为\(0\)(如果把选择设为\(1\),不选设为\(0\))。证明很简单,就是在矩形中画任意一个子矩形都只能将这三点中的两个或零个点包到矩形里头去,所以最终异或起来只能为\(0\)(即只需要知道这三个元素中的两个就能得到第三个)

类似的,发现除了左右关联(以第\(x\)列为轴)外,上下也是有关联的(以第\(x\)行为轴),到此发现了这是一个以中心十字为轴的矩形!(设第\(x\)行为行轴,第\(x\)列为列轴)

接下来就简单多了,由于\(n\leq 33\)的范围使得不能枚举所有点,那可以枚举行轴(而行轴又是以列轴为轴的,所以只需要枚举行轴的前\(x\)个元素即可推出整个行轴),然后枚举列轴的情况(同样只需要枚举前\(x\)个元素),发现如果行轴情况确定的情况下,列轴的\(x\)个元素带来的影响(即每一行的贡献)都是相互独立的(即不需要\(2^x\)去枚举),每个格子带来的影响也是独立的

上面可能讲得有点抽象,下面细化下过程 (还不懂就看代码吧)

  • 枚举第\(x\)行前\(x\)个格子选与不选 \(O(2^x)\)
  • 得出第\(x\)行整行的情况 \(O(n)\)
  • 枚举第\(i\)行第\(x\)个格子选与不选 \(O(n)\)
  • 由当前枚举状态枚举第\(i\)行每个格子\((i,j)\) \(O(n)\)
  • 推出格子\((i,j),(i+x,j),(i,j+x),(i+x,j+x)\) \(O(1)\)

总复杂度为\(O(2^xx^2)\),把\(x=17\)代进去大概为\(4e7\)

Code

#include <cstdio>

const int N=34;
int a[N][N],rw[N],ln[N];
int n,t; inline int calc(int i,int j){
int res=a[i][j],e;
e=a[i+t][j],res+=(rw[j]?-e:e);
e=a[i][j+t],res+=(ln[i]?-e:e);
e=a[i+t][j+t],res+=(ln[i]^rw[j+t]?-e:e);
return res>0?res:-res;
} int main(){
scanf("%d",&n);t=n+1>>1;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
scanf("%d",&a[i][j]); int ans=0;
for(int lim=1<<t,S=0;S<lim;++S){
int sum=0;
for(int i=1;i<=t;++i)
if(S&(1<<i-1))rw[i]=1,sum-=a[t][i];
else rw[i]=0,sum+=a[t][i];
for(int i=t+1;i<=n;++i){
rw[i]=rw[t]^rw[i-t];
if(rw[i])sum-=a[t][i];
else sum+=a[t][i];
} for(int i=1,r0,r1;i<t;++i){
r0=a[i][t]+(rw[t]?-a[i+t][t]:a[i+t][t]);
ln[i]=0;for(int j=1;j<t;++j)r0+=calc(i,j); r1=-a[i][t]+(rw[t]?a[i+t][t]:-a[i+t][t]);
ln[i]=1;for(int j=1;j<t;++j)r1+=calc(i,j);
sum+=r0>r1?r0:r1;
}ans=ans>sum?ans:sum;
}printf("%d\n",ans);
return 0;
}

题解-bzoj3901 棋盘游戏的更多相关文章

  1. 【题解】51nod1327 棋盘游戏

    那天和机房的同学们一起想了很久,然而并没有做出来……今天看了题解,的确比较巧妙,不过细细想来其实规律还是比较明显,在这里记录一下~ 当天自己做的时候,主要想到的是两点 : 1.按列dp 2.对行进行排 ...

  2. 1358 棋盘游戏[状压dp]

    1358 棋盘游戏  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 这个游戏在一个有10*10 ...

  3. HDU1281: 棋盘游戏(二分图匹配)

    棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  5. HDU1281 棋盘游戏 —— 二分图最大匹配 + 枚举

    题目链接:https://vjudge.net/problem/HDU-1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  6. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  7. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  8. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  9. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

随机推荐

  1. linux kill 命令【待完善】【转】

    kill 命令用来处理进程, 在linux中即可使用kill -9 pid 杀死进程 , 也可使用kill -KILL pid 等价的命令来执行. HUP 1 终端断线 INT 2 中断(同 Ctrl ...

  2. spring boot @Value Could not resolve placeholder

    @Configuration public class PropertySourcePlaceholderConfig { @Bean public PropertySourcesPlaceholde ...

  3. HDU - 6394 Tree(树分块+倍增)

    http://acm.hdu.edu.cn/showproblem.php?pid=6394 题意 给出一棵树,然后每个节点有一个权值,代表这个点可以往上面跳多远,问最少需要多少次可以跳出这颗树 分析 ...

  4. Ext.net 的锁定列要集中放到前面

    如题,Ext.net的锁定列要集中放在一起,不然的话,在使用排序的时候,会引起实际排序列错乱比如有A,B,C,D四列,A,C锁定,最终显示为A C | B D,这个时候如果点击B时,发现排序跑到了C上 ...

  5. 华为平板安装APK,提示“该安装包未包含任何证书”

    有的平板上会有错误现象 打包时签名勾选v1即可.

  6. springboot13 发布和监听事件

    spring中的事件驱动模型Event(也叫发布订阅模式),是观察者模式的一个典型的应用 好处:业务解耦,在不影响原来业务逻辑的情况下,加入其它业务 场景: app上线后已实现用户注册功能,现需要在用 ...

  7. 关于MySQL数据库——增删改查语句集锦

    一.基本的sql语句 CRUD操作:create 创建(添加)read 读取update 修改delete 删除 1.添加数据insert into Info values('p009','张三',1 ...

  8. python中的optionParser模块

    Python 有两个内建的模块用于处理命令行参数:一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数:另一个是 optparse,它功能强大,而 ...

  9. list vector map set (转)

    List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]. Vector对于随机 ...

  10. 第26月第22天 iOS瘦身之armv7 armv7s arm64选用 iOS crash

    1.iOS瘦身之armv7 armv7s arm64选用 机器对指令集的支持是向下兼容的,因此armv7的指令集是可以运行在iphone5S以上的,只是效率没那么高而已~ 但是由于苹果要求必须支持ar ...