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. vue实现筛选功能,文字选中变色

    <template> <Poptip trigger="hover" title="Title" content="content& ...

  2. .net面式题

    .Net httphandler与httpmodule区别 动态控件在postback能否保存下来(不能) 序列化(对象到其他格式(xml/json/byte...)JavaScriptSeriali ...

  3. SQLite 数据库介绍和基本用法

    Ø  简介 SQLite 是一款轻量级的关系型数据库,同时也是一种嵌入式数据库,与 Oracle.MySQL.SQL Server 等数据库不同,它可以内嵌在程序中,是程序中的一个组成部分.所以,经常 ...

  4. luogu 1850 换教室 概率+dp

    非常好的dp,继续加油练习dp啊 #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) ...

  5. 002_Add Two Numbers

    # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # sel ...

  6. IDEA对新建java线程池的建议

    1 代码片段 ExecutorService pool = Executors.newCachedThreadPool(); 2 建议的三种模板 A 第一种,采用Apache的common.lang3 ...

  7. python的for循环、while循环

    1.for循环使用之乘法表 for i in range(1,10): for j in range(1,i+1): print('%s * %s = %s '%(j,i,i*j),end='') p ...

  8. Java基础_0303:封装性初步

    class Book { // 定义一个新的类 private String title; // 书的名字 private double price; // 书的价格 public void getI ...

  9. 【mmall】IDEA中Service层无法识别Mapper,但是代码通过问题

    解决方案

  10. 7-10 多项式A除以B (25 分)

    题目链接:https://pintia.cn/problem-sets/1108548596745592832/problems/1108548661014913033 题目大意: 这仍然是一道关于A ...