传送门

发现 $n$ 很小,考虑状压 $dp$,但是如果强行枚举列并枚举置换再转移复杂度太高了

考虑推推结论,发现我们只要保留列最大值最大的 $n$ 列即可,证明好像挺显然:

假设我们让列最大值比较小的列贡献给某一行,那么由抽屉原理发现这意味着列最大值排名前 $n$ 的某一列一定没对答案贡献,

此时我们完全可以用那一列的最大值替换原本这一列对答案的贡献,这种情况同样可以推广到列最大值比较小的列贡献给多行的情况

所以证明就完成了

保留完最大的 $n$ 列,然后直接暴力 $dp$,设 $f[i][S]$ 表示考虑完前 $i$ 列,确定了的行的集合为 $S$ 时的最大值

那么转移就枚举子集,比子集多出来确定的行即为第 $i$ 列对答案贡献的行

增加的贡献设为 $mx[i][S]$ 表示第 $i$ 列,贡献的集合为 $S$ 时的最大值,这个可以枚举置换 $2^n \cdot n^2$ 预处理

然后枚举子集进行 $dp$ 的复杂度为 $3^n \cdot n$ ,总复杂度算一下达到了 $1e8$ 的级别

但是 $CF$ 评测机比较快并且这题时间限制比较充裕,稳得要死.jpg

多组数据注意要清空

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=,M=;
int T,n,m,mx[N][<<N],f[N][<<N];
struct dat {
int a[N],b[N];
inline bool operator < (const dat &tmp) const {
for(int i=n-;i>=;i--)
if(b[i]!=tmp.b[i]) return b[i]<tmp.b[i];
return ;
}
}d[M];
int main()
{
T=read();
while(T--)
{
n=read(),m=read();
for(int i=;i<n;i++)
for(int j=;j<m;j++) d[j].a[i]=d[j].b[i]=read();
for(int i=;i<m;i++) sort(d[i].b,d[i].b+n);
sort(d,d+m); reverse(d,d+m); int Mx=(<<n)-;
for(int i=;i<n;i++)
for(int j=;j<=Mx;j++) mx[i][j]=;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
for(int k=;k<=Mx;k++)
{
int t=;
for(int l=;l<n;l++)
if((k>>l)&) t+=d[i].a[(j+l)%n];
mx[i][k]=max(mx[i][k],t);
}
for(int i=;i<n;i++)
for(int j=;j<=Mx;j++) f[i][j]=(i== ? mx[i][j] : );
for(int i=;i<n;i++)
for(int o=;o<=Mx;o++)
{
f[i][o]=mx[i][o];
for(int p=o;p;p=(p-)&o)
f[i][o]=max(f[i][o],f[i-][p]+mx[i][o^p]);
}
printf("%d\n",f[n-][Mx]);
for(int i=;i<m;i++)
for(int j=;j<n;j++) d[i].a[j]=d[i].b[j]=;//这里要记得清空啊
}
return ;
}

Codeforces 1209E2. Rotate Columns (hard version)的更多相关文章

  1. codeforces#1290E2 - Rotate Columns (hard version)(子集dp)

    题目链接: https://codeforces.com/contest/1209/problem/E2 题意: 给出$n$行和$m$列 每次操作循环挪动某列一次 可以执行无数次这样的操作 让每行最大 ...

  2. Codeforces Round #584 E2. Rotate Columns (hard version)

    链接: https://codeforces.com/contest/1209/problem/E2 题意: This is a harder version of the problem. The ...

  3. 状压DP--Rotate Columns (hard version)-- Codeforces Round #584 - Dasha Code Championship - Elimination Round (rated, open for everyone, Div. 1 + Div. 2)

    题意:https://codeforc.es/problemset/problem/1209/E2 给你一个n(1-12)行m(1-2000)列的矩阵,每一列都可以上下循环移动(类似密码锁). 问你移 ...

  4. Codeforces 496C - Removing Columns

    496C - Removing Columns 思路:暴力,用vis标记数组实时记录一下之前的行i+1和上一行i否全相等,false表示全相等. 代码: #include<bits/stdc++ ...

  5. CodeForces 1118F2. Tree Cutting (Hard Version)

    题目简述:给定$n \leq 3 \times 10^5$个节点的树,其中一部分节点被染色,一共有$k$种不同的颜色.求将树划分成 $k$ 个不相交的部分的方案数,使得每个部分中除了未染色的节点以外的 ...

  6. codeforces#1165 F2. Microtransactions (hard version) (二分+贪心)

    题目链接: https://codeforces.com/contest/1165/problem/F2 题意: 需要买$n$种物品,每种物品$k_i$个,每个物品需要两个硬币 每天获得一个硬币 有$ ...

  7. Codeforces 1304F2 Animal Observation (hard version) 代码(dp滑动窗口线段树区间更新优化)

    https://codeforces.com/contest/1304/problem/F2 #include<bits/stdc++.h> using namespace std; ; ...

  8. Codeforces 1326F2 - Wise Men (Hard Version)(FWT+整数划分)

    Codeforces 题目传送门 & 洛谷题目传送门 qwq 这题大约是二十来天前 AC 的罢,为何拖到此时才完成这篇题解,由此可见我是个名副其实的大鸽子( 这是我上 M 的那场我没切掉的 F ...

  9. Codeforces 1446D2 - Frequency Problem (Hard Version)(根分)

    Codeforces 题面传送门 & 洛谷题面传送门 人菜结论题做不动/kk 首先考虑此题一个非常关键的结论:我们设整个数列的众数为 \(G\),那么在最优子段中,\(G\) 一定是该子段的众 ...

随机推荐

  1. 翻译一篇英文文章,主要是给自己看的——在ASP.NET Core Web Api中如何刷新token

    原文地址 :https://www.blinkingcaret.com/2018/05/30/refresh-tokens-in-asp-net-core-web-api/ 先申明,本人英语太菜,每次 ...

  2. unittest详解(四) 批量执行用例(discover)

    前面我们说了,对于不同文件用例,我们可以通过addTest()把用例加载到一个测试套件(TestSuite)来统一执行,对于少量的文件这样做没问题,但是如果有几十上百个用例文件,这样做就太浪费时间了. ...

  3. python3 类的属性、方法、封装、继承及小实例

    Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法. 对象可以包含任意数量和类型的数据. p ...

  4. [BZOJ2286][Sdoi2011]消耗战(虚树上DP)

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6457  Solved: 2533[Submit][Statu ...

  5. C++入门经典-例2.5-使用附加格式说明scanf函数的格式输入

    1:代码如下: // 2.5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" int main() { long iLong; /*长整型变 ...

  6. ES6 知识拓展

    1.冻结对象 Object.freeze(obj) 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性.可配置性 ...

  7. 造题inginging

    造个题 模拟+sort+贪心 蚕丛及鱼凫,造题何茫然 U74939 小歪被抓走了 代码(不知道对不对哦) #include<bits/stdc++.h> using namespace s ...

  8. kotlin之字符串

    在kotlin 中 使用String 表示字符串类型,如下二类字符串 一 普通字符串 var s1 = "hello world" 二 保留原始格式的字符串 var s2 = &q ...

  9. Rate 评分

    评分组件 基础用法 评分被分为三个等级,可以利用颜色对分数及情感倾向进行分级(默认情况下不区分颜色).三个等级所对应的颜色用过colors属性设置,而它们对应的两个阈值则通过 low-threshol ...

  10. [mysql]多个字段确定唯一性-联合唯一索引

    一.联合唯一索引项目中需要用到联合唯一索引: 例如:有以下需求:每个人每一天只有可能产生一条记录:处了程序约定之外,数据库本身也可以设定: 例如:t_aa 表中有aa,bb两个字段,如果不希望有2条一 ...