CF 321D

大概题意:

有一个N*N的矩阵,N恒为奇数,设X=(N+1)/2,我们每次可以对其中X*X的子矩阵进行正负取反的操作,问经过操作可以得到的矩阵和的Max

(N<=33)

Eg.

Input

3

3 -1 -1

1 -1 1

-1 1 -1

Output

9

Hint;

3 -1 -1       3 1 1           3 1 1           3 1 1

1 -1  1   -> 1 1 -1  ->    1 -1 1 ->      -1 1 1

-1 1 -1       -1 1 -1       -1 -1 1           1 1 1

解法:

我们发现x=(n+1)/2,所以有一个很重要的结论。

设f[i][j]表示(i,j)这个格是否翻转,那么有f[i][j]^f[i][x]^f[i][j+x]=0,f[i][j]^f[x][j]^f[i+x][j]=0

因为一次操作范围为x*x,一定同时覆盖三者中的两者,所以无论怎么操作它们异或的值恒为0。

我们发现整个N*N的方格可以被分成四个部分。

而且每个区内对应的四个格子是独立的,可以单独的计算。

因此我们只需枚举中间那一行一列的值,然后对于如图所示的四个格子单独贪心地计算即可。复杂度O(2^N*N^2)。

但这样仍然会超时!

随着研究我们发现,行与行之间也是独立的,我们不需要枚举中间一列的每个状态,而是枚举完中间一行后,对于行逐行单独贪心计算,复杂度变为O(2^X*X^2),可以通过此题

End.

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

int a[41][41],col[41],f[41];
int ans,n,i,j,x;
int g[35][35][2][2][2];
bool vs[35][35][2][2][2];

int Test(int y,int z)
{
    int ts,tt,res,i,nt;
    nt=col[x]^z;
    res=0;
    if(z)res-=a[y][x];
    else res+=a[y][x];
    if(nt)res-=a[y+x][x];
    else res+=a[y+x][x];
    for(i=1;i<x;i++){
        if(vs[y][i][col[x]][z][col[i]])res+=g[y][i][col[x]][z][col[i]];
        else{
            f[1]=1;f[2]=f[1]^z;f[3]=f[1]^col[i];f[4]=f[3]^nt;
            ts=0;
            if(f[1])ts-=a[y][i];
            else ts+=a[y][i];
            if(f[2])ts-=a[y][i+x];
            else ts+=a[y][i+x];
            if(f[3])ts-=a[y+x][i];
            else ts+=a[y+x][i];
            if(f[4])ts-=a[y+x][i+x];
            else ts+=a[y+x][i+x];
            f[1]=0;f[2]=f[1]^z;f[3]=f[1]^col[i];f[4]=f[3]^nt;
            tt=0;
            if(f[1])tt-=a[y][i];
            else tt+=a[y][i];
            if(f[2])tt-=a[y][i+x];
            else tt+=a[y][i+x];
            if(f[3])tt-=a[y+x][i];
            else tt+=a[y+x][i];
            if(f[4])tt-=a[y+x][i+x];
            else tt+=a[y+x][i+x];
            res+=max(ts,tt);
            vs[y][i][col[x]][z][col[i]]=true;
            g[y][i][col[x]][z][col[i]]=max(ts,tt);
        }
    }
    return res;

}

void Work(int zt)
{
    int i,tmp;
    for(i=1;i<=x;i++){
        if((zt&(1<<(i-1))))col[i]=1;
        else col[i]=0;
    }
    for(i=x+1;i<=n;i++)col[i]=col[x]^col[i-x];
    tmp=0;
    for(i=1;i<=n;i++){
        if(col[i])tmp-=a[x][i];
        else tmp+=a[x][i];
    }
    for(i=1;i<x;i++)tmp+=max(Test(i,0),Test(i,1));
    if(tmp>ans)ans=tmp;
}

int main()
{
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)scanf("%d",&a[i][j]);
    x=(n+1)/2;
    ans=-2147483647;
    for(i=0;i<(1<<x);i++)Work(i);
    printf("%d\n",ans);
}
时间: 2024-08-03 20:46:43

CF 321D的相关文章

微信 {&quot;errcode&quot;:40029,&quot;errmsg&quot;:&quot;invalid code, hints: [ req_id: Cf.y.a0389s108 ]&quot;}

{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"} 问题:微信网页授权后,获取到 openid 了,一刷新又没了 微信网页授权获取到的 code 只能使用一次(5分钟内有效),使用一次后,马上失效. 页面授权跳转成功,根据 code 也换取到 openid 了. 此时刷新页面,并不会再次进行授权,而是直接刷新了一下上一次授权跳转后的链接,带的还是

CF with friends and user&#39;s influence considered on NYC data(updated Aug,11st)

Here is the code link: https://github.com/FassyGit/LightFM_liu/blob/master/U_F1.py I use NYC data as other experimens. The split of the training data was seperated by the timeline, and I have normalised the interaction matrix by replacing the checkin

CF 750

今天CF打的块残废了     就是一废物 A 在24点之前到 直接模拟即可 #include<stdio.h> #include<algorithm> #include<cstring> #include<string> #include<cmath> using namespace std; #define LL long long #define MAXN 1010 #define inf 1000000000.0 int main() {

CF #394 (2) 5/6

Codeforces Round #394 (Div. 2) 总结:有毒的一场比赛.做了三题,结果A被叉,B.C挂综测,还hack失败一发,第一次在CF体会到了-50分的感觉..不知道是不是人品好,比赛时room炸了,然后,unrated.. A  水题,判一下0 0,然后abs(a-b)<=1 B  水题,组个间距比较一下,但一个数的时候要判一下 C  直接暴力上的题 D  也是xjb暴力 题意:给出n,l,r, a[], p[],另有两个数组b[], c[],ci=bi-ai.l<=ai,

一场CF的台前幕后(上)——转

前奏 大约4月份的时候,业界毒瘤pyx噔噔噔跑过来说:“酷爱!我YY了一道题!准备当CF的C” 我当时就被吓傻了."Yet another Chinese round?" “区间取模,区间求和” 感觉这题还不错?不过pyx嫌水了…… 好办!当时我刚刚出完动态仙人掌不久,于是一拍脑袋说:把这个问题出到仙人掌上去! 当然被pyx鄙视了…… 后来一直就没啥动静,直到5月底的CTSC. 试机的时候pyx给我看了套他出的神题……里面有一道题……我不小心读成了下面这个样子: “给定n个m维的模2意

[2016-03-22][CF][69A][Young Physicist]

时间:2016-03-22 19:41:34 星期二 题目编号:[2016-03-22][CF][69A][Young Physicist] 题目大意:判断向量和是否为0 分析:对应坐标相加 遇到的问题:不能用x+y+z来判断是否都为0,除非输入都是正数 #include <cstdio> using namespace std; int main(){ int a,b,c,x,y,z,n; x = y = z = 0; scanf("%d",&n); for(in

ARC下OC对象和CF对象之间的桥接(bridge)

在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环境下编译器不会自动管理CF对象的内存,所以当我们创建了一个CF对象以后就需要我们使用CFRelease将其手动释放,那么CF和OC相互转化的时候该如何管理内存呢?答案就是我们在需要时可以使用__bridge,__bridge_transfer,__bridge_retained,具体介绍和用法如下

【CF 520D】Cubes

[CF 520D]Cubes 怎么说呢--英语阅读题+超级大模拟-- 最重要的是知道怎么出来的数据...题意好懂 xy坐标内给出几个单位正方形 以正方形左下点坐标给出 y=0为地面 正方形下面或者左右下方至少存在一个正方形他才能稳定.. 正方形按0~m-1标号 每次只能取出不影响整体结构的正方形 甲乙玩一个游戏 交替取正方形 每取下一个按从左到右的顺序排好 得到一个大数 重点来了! 取出的数是m进制 转换为十进制是最终结果 甲希望结果最大 乙希望结果最小 问结果为多少 甲先取 题意明白了模拟就行

cf 148D Bag of mice

The dragon 选一只老鼠,然后会跑掉一只 the princess选一只老鼠,不会跑出另外的老鼠 求the princess赢的概率 1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<vector> 5 #include<queue> 6 #include<stack> 7 #include<algorithm> 8 #inc