Codeforces 1209E2. Rotate Columns (hard version)
时间:2019-09-16
本文章向大家介绍Codeforces 1209E2. Rotate Columns (hard version),主要包括Codeforces 1209E2. Rotate Columns (hard version)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
发现 $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=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=13,M=2007; int T,n,m,mx[N][1<<N],f[N][1<<N]; struct dat { int a[N],b[N]; inline bool operator < (const dat &tmp) const { for(int i=n-1;i>=0;i--) if(b[i]!=tmp.b[i]) return b[i]<tmp.b[i]; return 0; } }d[M]; int main() { T=read(); while(T--) { n=read(),m=read(); for(int i=0;i<n;i++) for(int j=0;j<m;j++) d[j].a[i]=d[j].b[i]=read(); for(int i=0;i<m;i++) sort(d[i].b,d[i].b+n); sort(d,d+m); reverse(d,d+m); int Mx=(1<<n)-1; for(int i=0;i<n;i++) for(int j=1;j<=Mx;j++) mx[i][j]=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=1;k<=Mx;k++) { int t=0; for(int l=0;l<n;l++) if((k>>l)&1) t+=d[i].a[(j+l)%n]; mx[i][k]=max(mx[i][k],t); } for(int i=0;i<n;i++) for(int j=0;j<=Mx;j++) f[i][j]=(i==0 ? mx[i][j] : 0); for(int i=1;i<n;i++) for(int o=0;o<=Mx;o++) { f[i][o]=mx[i][o]; for(int p=o;p;p=(p-1)&o) f[i][o]=max(f[i][o],f[i-1][p]+mx[i][o^p]); } printf("%d\n",f[n-1][Mx]); for(int i=0;i<m;i++) for(int j=0;j<n;j++) d[i].a[j]=d[i].b[j]=0;//这里要记得清空啊 } return 0; }
原文地址:https://www.cnblogs.com/LLTYYC/p/11526520.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- flutter 输入框组件TextField的实现代码
- Mac通过不同终端SSH连接远程服务器的讲解
- Linux关于透明大页的使用与禁用介绍
- linux中使用grep命令详解
- linux下使用cmake编译安装mysql的详细教程
- Linux CentOS 7.0中java安装与配置环境变量的步骤详解
- Linux下进程数量的限制pid_max的配置方法
- linux 进程数最大值修改方法
- Linux通过设备号找到设备的方法
- linux环境下安装 openOffice 并启动服务 的方法
- Linux下如何查杀stopped进程详解
- Linux文件服务器实战详解(匿名用户)
- ubuntu16.0.4 设置固定ip地址的方法
- Linux文件服务器实战详解(虚拟用户)
- Linux CentOS下安装Tomcat9及web项目的部署