20210804 noip30
考场
第一眼感觉 T1 是状压 DP,弃了。T2 好像也是 DP???看上去 T3 比较可做。
倒序开题。T3 暴力是 \(O(pn\log p)\)(枚举 \(x\),二分答案,看能否分成合法的不超过 \(k\) 组),先写个随机化,和暴力拍了一下发现正确率不太行,退火收敛太慢,只能爬山了,结果还不如直接随机???打表发现峰值特别多。。。死了。强行让退火快速收敛+随机化卡时到 0.98s,拍了拍发现 \(n,p\le5000\) 的时候正确率还行。没注意时间,写完 8.30 了。
T2 完全不会做,直接暴力。手玩数据发现和逆序对有关,但还是只会判无解,后来写了个复杂度不明(也许是 \(O(ans)\))的做法,一分也没骗到。不会造数据,随机了一些发现都是无解。。。爬了
9.30 才开 T1,想了想 DP(根本就不是 DP 啊)就写暴力了。写了 \(O(2^nn\sum m)\) 的暴力,分 \(\sum m\) 的大小用 bitset
或 bool
做背包,发现有一个 \(n=17,m\le2\times10^4\) 的点不会做(其实是 \(O(3^n)\) 枚举每个数不要/放第一个集合/放第二个),一直想到结束。
res
rk14 30+20+50
T3 退火还是太慢,导致后面的点全 T 了。(不然能拿 60~70pts)
rk1 yzf 45+100+50
rk3 牛宏昊 90+20+40
rk5 ycx 75+20+50
rk6 wcr 80+0+60
rk7 刘荣信 15+20+100
rk9 zjj 35+20+70
总结
主要死在了 T1,如果不从 DP 的方向想拿到 70pts 及以上还是比较容易的,以后不要直接确定一个方向,先直接想想,想不出来再根据感觉想特定的算法。
乱搞能力还是太死板,这场的 T1 T3 数据都水,各种做法都能拿到高分甚至 A
毛一琛
meet in the middle
先爆算前 \(\frac n2\) 个数的状态,记下差值和并集。
再枚举后 \(\frac n2\) 个,对于每个差值查和前 \(\frac 2n\) 中和它相同的状态(最多 \(2^{\frac n2}\) 个),然后把两个状态的或计入答案。
时间复杂度 \(O(6^{\frac n2})\)。题解说调整前后的大小能更快,但实测 \(\frac n3,\frac{2n}3\) 都不如 \(\frac n2\)
我选择了用 map
离散化差值,vector
存每个差值的状态,bool
数组去重,貌似不是正解(跑得很慢)
code
const int N = 22;
int n,a[N];
int m,ind,ans;
bool vis[1<<N];
unordered_map<int,int> id;
vector<int> state[1<<N];
void dfs1(int u,int del,int s) {
if( u > m ) {
if( !id.count(del) ) id[del] = ++ind;
state[id[del]].pb(s);
return;
}
dfs1(u+1,del,s);
dfs1(u+1,del+a[u],s|(1<<u-1));
dfs1(u+1,del-a[u],s|(1<<u-1));
}
void dfs2(int u,int del,int s) {
if( u > n ) {
if( !id.count(del) ) return;
int i = id[del];
for(int t : state[i]) vis[s|t] = 1;
return;
}
dfs2(u+1,del,s);
dfs2(u+1,del+a[u],s|(1<<u-1));
dfs2(u+1,del-a[u],s|(1<<u-1));
}
signed main() {
read(n); m = n/2.0;
For(i,1,n) read(a[i]);
dfs1(1,0,0);
dfs2(m+1,0,0);
for(int i = 1, j = 1<<n; i < j; ++i) ans += vis[i];
write(ans);
return iocl();
}
毛二琛
下文将 \([0,n-1]\) 对应到 \([1,n]\)
首先如果有 \(i=p_i\) 那么无解,但数据中没有,所以不用判
问题可以转化为 \(n-1\) 个数排列,对 \(i,i+1\) 的前后顺序有要求(这点保证了每个排列对应一个答案),求方案数。
先处理前后顺序。设 \(cmp[i]=0\) 表示 \(i\) 在 \(i+1\) 的前面,\(=1\) 表示在后面。若 \(i<p_i\),那么 \(cmp[i-1]=1\)(先要把数 \(p_i\) 从 \(i\) 换到 \(i+1\) 才能换 \(i-1,i\)),\(cmp[i..p_i-2]=0\)(数 \(p_i\) 要从 \(i\) 一直向右换到 \(p_i\),期间换了左边的才能换右边,不然数 \(p_i\) 就无法继续向右了),\(cmp[p_i-1]=1\)(换 \(p_i-1,p_i\) 后数 \(p_i\) 一定在 \(p_i\) 上,此后换 \(p_i,p_i+1\) 会导致数 \(p_i\) 被换离);\(i>p_i\) 的情况同理。
考虑 DP。设 \(f[i,j]\) 为前 \(i\) 个数中 \(i\) 排在第 \(j\) 位的方案数,转移:
\sum_{k=j}^{i-1}f[i-1,k],cmp[i-1]=1
\\
\sum_{k=1}^{j-1}f[i-1,k],cmp[i-1]=0
\end{matrix}\right.
\]
\(cmp[i-1]=1\) 时 \(k\in[j,i-1]\) 是因为在前 \(i\) 个数中 \(i-1\) 排在第 \(j\) 位之后,那么在前 \(i-1\) 个数中就要排在 \([j,i-1]\),可以看作将 \(i\) 插进前 \(i-1\) 个数排列的第 \(j\) 位,那么原来的 \(j..i-1\) 位就要向右移一位。第二维可以前缀和优化,时间复杂度 \(O(n^2)\)
code
const int N = 5e3+5, mod = 1e9+7;
int n,a[N];
int f[N][N],sum[N][N];
bool cmp[N];
signed main() {
read(n);
For(i,1,n) read(a[i]), ++a[i];
for(int i = 1; i < n; ++i)
if( i < a[i] ) cmp[i-1] = cmp[a[i]-1] = 1;
else for(int j = a[i]; j < i-1; ++j) cmp[j] = 1;
f[1][1] = sum[1][1] = 1;
for(int i = 2; i < n; ++i) {
if( cmp[i-1] ) For(j,1,i) f[i][j] = (sum[i-1][i-1]-sum[i-1][j-1]+mod)%mod;
else For(j,1,i) f[i][j] = sum[i-1][j-1];
For(j,1,n) sum[i][j] = (sum[i][j-1] + f[i][j]) %mod;
}
write(sum[n-1][n-1]);
return iocl();
}
毛三琛
需要加一个优化:随机枚举 \(x\),\(O(n)\) 判断在当前答案下能否分成不超过 \(k\) 组,如果可以再去二分,时间复杂度 \(O(qn+n\log n\log q)\)
code
const int N = 1e4+5;
int n,p,m,a[N];
int ans,b[N],q[N];
mt19937 mt(time(0));
bool check(int x) {
int res = 1, sum = 0;
For(i,1,n) {
if( b[i] > x ) return 0;
if( sum+b[i] <= x ) sum += b[i];
else ++res, sum = b[i];
}
return res <= m;
}
int calc(int x) {
int l = 1, r = ans;
while( l < r ) {
int mid = l+r>>1;
if( check(mid) ) r = mid;
else l = mid+1;
}
return l;
}
signed main() {
read(n,p,m);
For(i,1,n) read(a[i]), ans += a[i];
for(int i = 0; i < p; ++i) q[i] = i;
shuffle(q,q+p,mt);
for(int i = 0; i < p; ++i) {
For(j,1,n) b[j] = (a[j] + q[i]) %p;
if( check(ans) ) ans = calc(q[i]);
}
write(ans);
return iocl();
}
20210804 noip30的更多相关文章
- noip30
T1 一眼看,觉得是个状压,然而又觉得不太行,去打暴力了,然而暴力都打挂的我biss. 正解: 还是暴力,考虑 \(meet \; in \; the \; middle\) 显然对于每个数,只有三种 ...
- win 常用修复蓝屏,系统比对最后更新20210804
您可以尝试以下方案: 在管理员命令提示符下键入以下命令:Dism /Online /Cleanup-Image /ScanHealth这条命令将扫描全部系统文件并和官方系统文件对比,扫描计算机中的不一 ...
- 调用免费API查询全年工作日、周末、法定节假日、节假日调休补班数据
前言 日常开发中,难免会用到判断今天是工作日.周末.法定节假日.节假日调休补班做一些业务处理,例如:仅在上班时间给用户推送消息.本文记录调用免费API查询全年工作日.周末.法定节假日.节假日调休补班数 ...
- 阿里云RocketMQ定时/延迟消息队列实现
新的阅读体验:http://www.zhouhong.icu/post/157 一.业务需求 需要实现一个提前二十分钟通知用户去做某件事的一个业务,拿到这个业务首先想到的最简单得方法就是使用Redis ...
- SprintBoot简单入门
1.什么是SpringBoot SpringBoot是基于Spring的基础上提供了一套全新的框架,其目的是为了在开发时简化Spring的相关配置及开发过程.在SpringBoot未出来之前,准备搭建 ...
- 用Python预测双色球福利彩票中奖号码(请不要当真)
前言 双色球是中国福利彩票的一种玩法. 红球一共6组,每组从1-33中抽取一个,六个互相不重复.然后蓝球是从1-16中抽取一个数字,这整个组成的双色球 python从零基础入门到实战 今天,我们就用P ...
- 破解加速乐-java
记录一哈自己遇到的简单站点的破解 Talk is cheap,show you the code! import com.google.gson.Gson; import com.google.gso ...
- (11)MySQL进阶篇SQL优化(InnoDB锁问题排查与解决)
1.概述 前面章节之所以介绍那么多锁的知识点和示例,其实最终目的就是为了排查与解决死锁的问题,下面我们把之前学过锁知识重温与补充一遍,然后再通过例子演示下如果排查与解决死锁. 2.前期准备 ●数据库事 ...
- linux centos7 df命令
2021-08-04 1. df 命令简介 linux 中 df 命令的功能是用来检查 linux 服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信 ...
随机推荐
- 电脑桌面与群晖NAS双向实时同步-20210105
电脑桌面与群晖NAS双向实时同步 2021年1月15日星期五 一.购买群晖DS920+网络存储服务器.NEC超轻笔记本电脑(重量小于800克).小米10至尊版安卓智能手机和intel i9 1 ...
- 从net到java:java快速入门
学习java那是不可能的,到为什么不学习一下呢.仅为总结.希望自己在不久的将来能书写优美的java程序.加油!奥利给 1.注释 注释的重要性不言而喻,我们不管写什么代码注释必不可少,那么java的注释 ...
- SpringBoot-技术专区-用正确的姿势如何用外置tomcat配置及运行(Tomcat优化分析)
前提概要 在特别特殊的时候,我们可能需要外置tomcat去运行程序,例如alitomcat等特殊场景,方便我们去定时化开发项目或者其他特殊场景. 外置tomcat执行 pom.xml文件首先更改打包方 ...
- Linux 内核预备知识:浅析 offsetof 宏以及新手的所思所想
最近一头扎进了 Linux 内核的学习中,对于我这样一个没什么 C 语言基础的新生代 Java 农民工来说实在太痛苦了.Linux 内核的学习,需要的基础知识太多太多了:C 语言.汇编语言.数据结构与 ...
- Redis-01-基础
基本概念 1 基本概念 redis是一个开源的.使用C语言编写的.支持网络交互的.可基于内存也可持久化的Key-Value数据库(非关系性数据库) redis运维的责任 1.保证服务不挂 2.备份数据 ...
- Woc,考场(面试)忘记打平衡树怎么办,Trie救你命
Woc,考场(面试)忘记打平衡树怎么办,Trie救你命 文本只发布于博客园,其他地方出现本文均是未经许可的盗版. 算法导入 众所周知平衡树很难打(大佬除外),还老是调错.万一这种事情发生在关键时刻你就 ...
- 【网络编程】TCPIP_3_地址族与数据序列
目录 前言 3. 地址族与数据序列 3.1 分配给套接字的 IP 地址与端口号 3.2 参数 IP 地址 3.2.1 IPV4 地址的结构体 3.2.2 地址族(Address Family) 3.2 ...
- Pikahu-SQL注入模块和sqlmap经典用法
一.概述 SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的"数据"拼接到SQL语句中后,被当作SQL语句的一部分执行. 从而导 ...
- CTF-flask模板注入学习
今天又看到了一道这样的题,之前一直都学不明白的东西 反反复复给你看的时候,就想搞明白了. 我们做题的,需要知道flask是怎么运行的就行了. 这个就是一个最简单的flask应用,当我们访问的时候,就会 ...
- noip34
因为改不动T3而来水博客的屑 昨晚没睡好,大致看了一遍题面后,选择了死亡231,然后就死的很惨. T1 一开始大致看题面的时候,就略了一眼,加上没读全题,啥思路也没有,最后四十分钟滚回来看了看,发现就 ...