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-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-01 Xie Jingyi
今天开始学习数论方面的算法。这部分在NOIP中并不常出现,即使出现了也不会像高联这么难(。。。)。 什么是扩展欧几里得算法 所谓欧几里得算法,实际上就是辗转相除法——求两个数最大公约数的一种高效算法。而扩展欧几里得算法则是来源于于一类方程的解决: $$ax+by=gcd(a,b)$$ 这有点像是裴蜀定理的一般形式。和裴蜀定理类似,这类方程也有无数多个整数解。如何高效率地求得它的一组特解呢? 代码 pascal procedure gcd_ex(a, b: longint; var d: longint; var x, y: longint); begin if b = 0 then begin 继续阅读 »
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-09-29 Xie Jingyi
链接:Link 耗时:0.028s 一道简单的动态规划,主要思路就是: 用f[i,j]表示到达(i,j)的最长路径的长度。找到每个最高点,从其开始向四周的低处搜索。如果该点已搜过并且f值大于当前长度则退出回溯。直到达到某个最低点为止。 不多说了,直接上代码: ```pascal const delta :array [1..4, 1..2] of integer = ((-1, 0), (1, 0), (0, 1), (0, -1)); //四个方向向量 var _: Integer; name: string; n, m, i, j, x: Integer; ans: longint 继续阅读 »
2014-09-27 Xie Jingyi
事实上我也不知道发生了什么,大概是几天前插了“小度Wifi”的缘故。没有任何征兆地,Wifi就用不了了。 其实我也不知道原理,大概是某个驱动被刷掉了。 下面是从网上找来的答案: sh sudo apt-get install wicd-daemon 做个记录。 继续阅读 »
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 // 继续阅读 »
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-09-23 Xie Jingyi
链接:The Tower of Babylon 耗时:0.015s 这是刘汝佳的紫书中"DAG中的动态规划"中的习题,我拿它用来熟悉DAG中的动态规划。 我们不妨进行逆向考虑:现堆上面的方块,然后考虑在下面进行叠加。这样子一来,影响决策的就只是最下面方块的尺寸了。 对于这种出现了"大套小"这样的二元关系的题,我们可以将其视为一个有向无环图:其中每个节点为一个状态,状态的转移是有固定的方向的(在此题中,状态转移为从小的方块到大的方块)。 但是这道题又不同于平常的DAG动态规划:若将边长视为状态的话,则要开一个巨大的数组,这是不可以接受的。因此,我们要换一种思维方式:只记录方块的序号和摆放的方式(如现将边长从小到大进行排序,然后 继续阅读 »
2014-09-22 Xie Jingyi
记得11年的时候,觉得这道题爆难,根本无从下手。三年后再次回顾,终于AC了,就当是对表达式求值和动态规划的复习吧。 题目:Link ```cpp // Accepted. include <iostream> define Mod 10007; using namespace std; typedef struct { long long v0; //当前值为0的个数 long long v1; //当前值为1的个数 char ch; //当前字符 } vertex; vertex f[100000]; void merge_sum(int p) { int w0 = f[p-1 继续阅读 »