1、20150919
<1> 购物
大概题意:你手上有n种面值的硬币,每种无限个,你希望带尽量少的硬币,但能够组成1-x之间的任意值。
题解:DP/贪心。
<2> 养猪
大概题意:有n个数,每次你可以选择一个数,选择完之后,第i个数会减少p[i](如果已经<=0,则记为0)。求每次选择数的总和。
总结:已经提醒的很明显了,我也看到了,想到了,但是写完之后就不知道了。呵呵。在动规的时候要与0取一次max。少了这句话什么分都没了。
题解:DP。
<3> 数位平方和
大概题意:定义S(n)表示n的各个数位的k次方的和,定义H(n)=min(n,S(n),H(S(n)))。求H[i](i∈[a,b]) mod 10^9+7。
题解:这道题存在一定的争议,因为这个奇怪的数列存在环。虽然这不影响得出答案,但是感觉上是不符合现实逻辑的。
<4> 扩散
大概题意:平面坐标系上有n个点,每次都会向四个方向扩散。扩散部分在下次也会扩散。求多少次能够使n个点全部相连。
总结:我原本以为曼哈顿距离+最小生成树这种鬼畜的算法是乱搞的,正确性是不足的,但是这就是正解的其中一种。然而,然而!最后求解的时候忘记是求最大值了,习惯性的把所有值加起来了,结果样例还对了,结果我测的数据也是对的!没话讲啊!全错。
题解:如上。另一种方法为二分。
2、20150920
<1> 第k短路径
大概题意:找一张图上的第k短路径。
题解:Dijkstra+A*算法,也可以用Dijkstra乱搞,甚至有复杂度较高但是依旧能够过的DFS乱搞。
<2> 最长公共子串
大概题意:求两个字符串的最长公共子串。
题解:后缀数组裸题。O(n^2)动规只有30分。
<3> 体育馆
大概题意:双重带权线段覆盖最大值问题。
题解:这道题和贪心什么的没有任何关系,起码目前还没有听说有这么做能够对的。已知唯一一个能够AC的是最小费用最大流,还有个动态规划,没听懂。详细解析一下最小费用最大流:
①处理费用:首先一定存在一个疑问:本题不存在费用,只有收益。这个地方设计得非常巧妙,由于在裸最小费用最大流中我们是尽可能找费用小的,这里我们尽可能找收益大的,那么我们可以把收益置为负数来作为费用计算,故存在最小费用即最大收益;
②构图思路:假设共有n天,首先,我们设置1~n共n个节点,将他们从小到大有向连接起来,对于每一条路径,收益为0,因为如果从第i天到第i+1天什么事都不干的话,是没有收益的;流量为2,因为有两块场地;
③添加企业:对于某家企业要求在第x天到第y天占用,收益为z。根据上述构图,如果要引入该家企业,则需要占用一块场地,则相当于需要1的流量,费用即收益的相反数。连接的两个点为第x点与第y+1点。
④源点汇点:设置0号节点和n+1号节点,费用,收益同样分别为2,0;
④跑最大流:从0号节点起跑最小费用最大流,答案即为最小费用/最大收益。
非常喜欢这种思路,虽然说网络流这一块复杂度普遍都比较高,常数也不小,但是对于小数据,或者是实在没有想到正解的情况下,用网络流也是不错的,代码相对来说并不难写。
3、20150921
<1> 侦察员
大概题意:存在一张3*n的0-1地图,要求从最左端走到最右端,只有0可以经过。当且仅当当前处于中间一行时,可以将身边8个格子的数值顺时针转移。求转移次数最少而满足条件。
题解:DP/记忆化搜索。
<2> 密码串
大概题意:存在一个密码串和原始串,要求还原原始串为答案。还原方式:对于答案的每一个字符,前面都会添加一个密码串,但是会夹杂一些其他的字符。
题解:O(n)模拟。
<3> 正面战场
大概题意:给出一个10^9内的数n,要求在10^9内找出若干个数a,使a*a的后九位数为n。n和a均允许存在前导0。
总结:我没话讲。真的傻逼了。唉。我死命着从完全平方数的性质和推论寻找奇偶关系优化,尾数判断优化等等若干,优化到1.8-3s,实在找不出了。结果可想而知是0分。考完后我看到了其他人的代码几乎是崩溃的。同样是枚举,我竟然没想到按位来搜?呵呵。
题解:首先可以明确是9位数,那么从第一位起从0到9枚举,只要当位满足,就递归到下一位。状态量大大减小,显然不是所谓的O(n^m)。呵呵。
<4> 拯救fish
大概题意:给出一张有向图,从1号点出发,每一次可以选择一个后继节点作为下一次更多的一个出发点。也就是说如果当前从1号点中选择了与其相连的2号点,下次,可以分别从1号点和2号点出发找节点。问最快可以几次找完所有节点。
总结:题目本身貌似std都有问题,暴力80分。我们有各种贪心方式,甚至连样例都过不了的贪心竟然AC了,想不通。我也曾想到过,但是显然错误得不能再错误了,也是又加了优化。但是加优化的过程中写错了一个傻逼地方,我真的无语,虽然我也不能确定这种方法是否存在完全正确性,但是90分总比40分好看。
题解:贪心。由于数据的问题我不能名正言顺地说哪种方法是对的。首先对于一个点u如果能够被点v选择,则称v为u的父亲节点。我的方法是,对于任意节点,首先预处理出能够选择节点的个数,以及他是否只有一个父亲,其父亲的儿子中存在这种节点的个数。最初将1号节点加入可操作节点集合中,对于当前处理的节点,优先选择那些只认当前节点为父亲的节点,其中又优先儿子节点最多的儿子节点,直到所有节点都在可操作节点集合中。