2014-09-24 Xie Jingyi
这是一道区间型DP,转移方程很简单,但在实现的过程中却遇见了很多坑,在此记录一下。 链接:Link 耗时:0.368s 容易想到,前i个数的划分情况可以由1,2,3...,i-1的划分情况来决定。因此很容易得到状态转移方程: d[i] = min(d[i], d[j]+1) //j = 0, 1, 2...n-1 并且 s[j+1, i]为回文串,初始条件:d[i] = i。 d[i]表示前i项的最小划分。这样一来状态转移的复杂度就为O($n^2$)。 但状态转移的判断呢?“回文串”是一个复杂的条件,判断一个串是否为回文串需要将该串至少遍历一遍。这样一来时间复杂度就上升为O($n^3$)了。而事实上在这种算法中有许多无谓的计 继续阅读 »
2014-10-01 Xie Jingyi
链接:Link 耗时:1.825s 这道题做的可真够久的:前前后后加起来将近有两个小时,因此当AC的那一刻,自己心中还是挺自豪的。 事实上,这是一道复杂一点的区间型动态规划,之所以说“复杂”,是因为它的状态转移是二维的:切蛋糕既可以横切,也可以纵切。由此我想到了分治算法: 假设一个矩形它所需要切的刀数是f,则f可以由组成该矩形的小矩形的f值决定。 因此,这个问题具有最优子结构。由于每个状态为一个矩形,因此需要4个维度来记录状态(及左上、右下两个顶点)。下面是横切时的状态转移方程,纵切时同理可得: f(up, down, left, right) = min{f(up, i, left, right) + f(i, dow 继续阅读 »
2014-10-01 Xie Jingyi
链接:Link 耗时:0.139s 前言 这道题的主要思路就是打表,看看Fibonacci数列模n几个一循环。但由于这题给的数太大了,从而在细节上耗了很久。在此记录一下: var x: qword; y: longint; begin x := 1<<64-1; y := 100; x := x mod y; //报错201 x := x mod qword(y); //正确 end. Code var a,b: qword; _, n, i, k, cnt: longint; f: array [1..1000000] of longint; fun 继续阅读 »
2014-10-06 Xie Jingyi
链接:Link 状态:Runtime Error 前言 这题做的可真够久的,整整三个小时。但即便如此,还是只过了一部分的点,另一部分报运行时错误——估计是哈希表设计的不太好。但这确实是一道好题,因此,在睡觉前决定记录一下。 分析 很容易便想到:用一个三元组$(x,y,z)$表示节点,表示内容为x的节点下跟着标号为y和z的左右子树。这样一来,一类相同的子树便可以唯一确定了,而不必每构造一棵子树就把整棵树遍历一遍。 对于三元组的储存,刚开始图方便,用了数组。查找也是用了$O(n)$的线性查找。磕磕碰碰写了两个多小时然后兴冲冲地提交,结果TLE了…………没办法,只好又花了半个小时写了一个哈希表,然后就是上文说过的情况了:Runti 继续阅读 »
2014-10-06 Xie Jingyi
链接:Link 耗时: 0.012s 前言 真是疯玩了几天,脑袋都残了,一道弱智题做了近一个小时。 Code var pre, mid, s: string; tree: array [1..50] of record l, r: integer; ch: char; end; cur: integer; function init: integer; var m: integer; begin readln(s); m := length(s) >> 1 + 1; pre := Copy(s, 1, m-1); mid 继续阅读 »
2014-10-15 Xie Jingyi
链接:Link 耗时:0.699s 思路 dfs(t, x, y, d, s)表示当前走了t步,在(x,y),上一个方向为d,s为一个求和用的辅助变量。 当前位置无法走完剩下的路时直接回溯。可节省接近2s的时间。 ps: 这道题虽然没有明说每个城市只走一次,但它的确那样判了,这一点坑了我好久。 Code //Accepted. const dx: array [1..4] of integer = (1, 0, 0, -1); dy: array [1..4] of integer = (0, 1, -1, 0); dir: array [1..4] of char = ('e', 'n', 's', 继续阅读 »
2014-10-17 Xie Jingyi
链接:Link 状态:WA 分析 做了两个小时,很可惜最终还是WA了。非常奇怪——和网上的C++代码运行结果完全一样,但却WA了。不过,在这里我还是记录一下解题的过程。 这道题数据量很小,直接爆搜每个空位,用*, +, -, #0来代表符号或不填。 Code const operators: array [1..4] of char = ('*', '+', '-', #0); //符号 var s: string; _, n: integer; op: array [0..10] of char; yes: Boolean; function toValue(ch: char): 继续阅读 »
2014-10-19 Xie Jingyi
链接:Link 耗时:2.232s 分析 粗看题目,不过就是要求这样一个式子:$\sum_{i=1}^n{[\frac{n}{i}]}$的值。但注意到:题目给的数据范围极大,有$2^{31}-1$之多,若遍历计算,则时间复杂度为$O(n)$,将严重超时,不可取。 而事实上,通过尝试我们可以发现:$\sum_{i=1}^{n}{[\frac{n}{i}]}=2*\sum_{i=1}^{\sqrt n}{[\frac{n}{i}]}-{[\sqrt n]}^2$,这是一个重要的结论。因为这条式子一旦成立,时间复杂度即可从$O(n)$降为$O(\sqrt n)$,这是一个极为可观的改善。下面我们来证明一下这个结论: 事实上,$$\su 继续阅读 »
2014-10-24 Xie Jingyi
链接:Link 耗时:0.679s 分析 本质上,这是一道求数列通项的题目。我们列出前几个字符串: $$01,$$ $$1001,$$ $$01101001,$$ $$1001011001101001,$$ $$\ldots$$ 如果用$S_i$表示第i个字符串中“00”的个数,则有: $$S_1=0,\ S_2=1,\ S_3=1,\ S_4=3,\ S_5=5,\ S_6=11,\ldots$$ 经过观察可以发现有如下规律: $$S_n=2\times S_{n-1}+{(-1)}^n$$ 求通项就简单了,换个元即可: $$S_n=\frac{1}{3}[{(-1)}^n+2^{n-1}]$$ 程序采用高精度实现。 Cod 继续阅读 »
2014-09-27 Xie Jingyi
链接:Link 耗时:0.586s 昨晚做的太急了,没时间写总结,正好下午有空,补上。 这是一道典型的树形动态规划,不是很难,但十分坑语言。思路大致如下: 对于第i个节点,用d(i)表示其上诉所需的最小工人数。若i为叶节点,则d(i)=1;否则,遍历求出i的子节点所对应的d值,并由小到大排序,取出最小的几个相加,即为d(i)。 很容易想到用递归来实现。但对于“子节点的d值的排序”实现起来却十分困难:因为事先不知道有多少个数。当然啦,如果是C++组,用vector可以轻松搞定,可至于P党,实现起来却难上加难。思来想去,决定试试Pascal的动态数组。磕磕碰碰调了近1个小时,终于AC了。 Code: ```pascal // 继续阅读 »