欢迎使用CSDN-markdown编辑器
来源:互联网 发布:linux系统哪个版本好 编辑:程序博客网 时间:2024/06/04 23:31
- 这次NOIP考完后原地爆炸.
Day1
心态直接爆炸,第二题模拟打了两个多小时最后却错了,心态原地爆炸,时间又不多了,结果其他的题目都没来得及认真思考
* T1:
就是一个简单的数学(zhao)归(gui)纳(lv),但是当时第一眼直接懵逼,woc我怎么从来没有见过这种第一题?
然后一看数据范围,绝对是找规律,然后找了一下觉得可能没有这么简单就去找方法最后没找到
(真是后悔当时没有坚持找下去,其实规律很简单)
** 方法
输出两个数的积减去它们的和
* T2:
一个模拟,考完感觉十分变态,而且我智障的当时没有想到用栈。
** 方法
就按照题目说的模拟就行了(用一个栈)
* T3:
这题要用到DP加最短路加判环,本来就DP不好,在加上当时没有时间了,连分都没有骗到。
** 方法
题意:求1~n路径长度<=1~n最短路+K的路径数
首先你可以考虑到Day1的DP去哪里了?
没错,你只要再注意一下K<=50就大概能想到这是一个与k有关的DP了
①:考虑30pts:K=0 右转P1608路径统计(P1144最短路计数可以顺带A掉)
②:考虑70pts:没有0边
考虑f[u][j]表示1->u,比dis1[u] (1~u的最短路)多j的路径数
那么对于u->v长为w的边
那么从1->u->v这条路径的长度就是dis1[u]+j+w-dis1[v]
如果dis1[u]+w-dis1[v]+j<=K
就可以从f[u][j]转移到f[v][dis1[u]+j+w-dis1[v]]
所以直接先从1跑最短路然后直接o(KM)DP就ok了
当然这样是有问题的
因为我们必须要先更新dis1小的点
所以要先按照dis1排个序再去转移就有70pts了
③:考虑100pts:
对于有0边的图,显然直接按照dis1小的是不行的
e.g a->b->c w=0
更新顺序显然是a,b,c,然后他又是一个有向图
所以考虑拓扑排序来确定0边两个端点的更新顺序
即对于0边,把其加入新图,然后对于新图拓扑排序确定”0点”的更新顺序
然后对于-1的情况显然是对于一条满足条件的路径上有一个0环
拓扑排序完了且入度!=0说明这个点在0环上
同一个0环上任意一个点到1的最短路和到n的最短路都一样
所以当这个点i,满足dis1[i]+disn[i] (i到n的最短路)<=dis1[n]+K时
就可以输出-1了
然后最后排序就是以dis1/disn为第一关键字,拓扑序为第二关键字排序再转移就ok了
–洛谷题解https://www.luogu.org/wiki/show?name=%E9%A2%98%E8%A7%A3+P3953
Day2
* 稍微调整了一下心态和策略,所以感觉更好。
* T1:
当时感觉还好,听说会爆long long,但是我开了根号,进哥说应该不会有事
在洛谷上测是满分实际的分数还不知道
** 方法
求出每两个点之间能不能到达,然后转换成bfs判是否联通就行
* T2:
一看还以为是最短路,后来又想了一下可能不一定行,但是没想出其他方法了
于是就用一个dijkstra加点判断(因为是求每段弧最小值所以我就求了每个点到终点(后面没有与之相连的点)的最短路之和取最小值)
** 方法
状压DP:
1.设f[dep][S]为到第dep层目前用了S状态的点的总方案数目
考虑在它的补集里面枚举下一层的点数,然后直接转移就行了。
f[i + 1][s1 | s2] = min(f[i + 1][s1 | s2], f[i][s1] + val[s2][s1]); 其中val[s2][s1]表示s2的每个点到s1所需要的最小总花费。
如果直接做的话是O(3^n * n^3)的
发现val这个东西对于每一个s1s2是一样的,那么预处理一下
先预处理点到集合的,在处理集合到集合的。
总复杂度O(3^n * n)
常数有点大。
2.n<=12,状压.
起点自定.
每条边的贡献为层数*边权.
每个点的连边不需要在意,只关注它对状态产生的贡献.(对于每个状态预处理,复杂度为O(2^n*n)).
从小到大枚举层数,然后枚举初始状态,再枚举转移后状态.由于预处理,复杂度为O(3^n*n).
(枚举转移的状态时,顺便统计每个新增点的贡献,而这个已经预处理完了)
总体来说是O(2^n*n+3^n*n)的
–由于并不会所以附上luogu答案
–https://www.luogu.org/wiki/show?name=%E9%A2%98%E8%A7%A3+P3959
* T3:
写这题的时候时间已经不多了,而且当时还以为最后一题是DP就没怎么敢写(然而后来进哥说就是线段树,我前一周才弄的呀)
结果写了个暴力就快下考了
** 方法
首先有一个非常明显的暴力是这么写的:
直接拿一个二维数组维护在每一个位置上的编号,然后暴力对齐就可以了
通过观察可以发现删除(x,y)位置的点,然后添加到(n,m)
只会影响到第x行和第m列,所以每次只要修改n+m个元素的位置
具体参考代码1(略过)
对于20%的数据,我们只要维护那些被修改过的行和最后一列,可以做到O(nq)
对于30%x=1的数据,我们发现只要在第一行删掉一个元素,然后放在(n,m),后面的元素整体往前
其实就是维护一个序列,一开始有多个元素,支持查找第x个元素并删除,以及在最后添加元素
我们可以用线段树维护,记录区间内有多少个可用点,
如果我们要查找第x个,而左区间有k个,若x<=k那么就往左区间走,否则在右区间查询第x-k个元素
具体参考代码2(略过)
对于100%的数据,我们发现其实就是维护n+1个序列,支持查找和删除第x个元素,以及在最后添加元素
前n个序列维护每一行的前m-1个元素,最后一个序列维护最后一列的元素
但是这样的话需要建n+1颗线段树,无法承受
但是可以发现一开始线段树中的元素是满的,并且一开始的元素编号十分有规律,可以直接计算
那么我们一开始就直接把所有线段树当作满的,用动态开点每次删点,后面加进来的点用vector储存,
当删除(x,y)时
如果y =m那么只要操作最后一列,如果是原来最后一列的元素,就直接计算,否则从vector中提取
如果y!=m那么先对第x行进行一次操作,转化成删除(x,m)位置的元素,然后再对最后一列进行操作
因为每次操作最多会加入两个元素,所以最多只会有O(2q)的元素储存在vector中
时间复杂度O(nlogn),空间复杂度O(nlogn)
具体参考代码3(略过)
因为是线段树,所以代码可以应该算比较短的,也非常好写
阅读全文
0 0
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- git 相关知识
- Angular4订阅(Subscribe)与取消
- 使用循环神经网络训练情感分析
- 经典笔试题:指针详解
- 在Android的webview中定制js的alert,confirm和prompt对话框的方法
- 欢迎使用CSDN-markdown编辑器
- simplest_ffmpeg_streamer加注释版
- [POJ] 2251 Dungeon Master
- 2-2 hanxin
- WebSocket总结
- Java和C++ Protect安全性
- [2017.11.18]作业12
- Mars老师Android视频教程笔记,欢迎指正
- jieba库最常用操作