做的第一场CodeChef,发现CodeChef的题目都很好啊,为期10天的比赛,没有难得做不出的题,但也并非都是简单题,以后应该会每个月都做的,并且尽量把解题报告发出来。
传送门:http://www.codechef.com/MAY11/
这是这场比赛中的非常规题,题目的大意就是给你一张无向图,每条边有两个权值,你需要求出一个割,其将无向图分为两个部分,要使得这两部分之间的边的第一权值之和比第二权值之和尽可能的小。
似乎想不出来什么太好的做法。随机生成一些数据,发现很多情况下,将某个点独立出来,其他点放在另外一边所得到的结果是很优的(其实这是天王告诉我的……),因此可以先进行这种计算,得到一个解。之后我又进行了大约50次随机划分,然后进行逐步随机调整,使得结果尽可能小。这样的方法得到的解就已经很优了。
- The Great Wall of Byteland (BWALL)
题目的大意就是问长度为N、宽度为2的方格被以下两种类型的砖块(可以旋转)填充满有多少种不同的方案。
XX X
X
这是陈题了,显然有递推公式Fn=2Fn-3+4Fn-2+Fn-1,由此可构造矩阵[0, 1, 0; 0, 0, 1; 2, 4, 1]使用快速幂做矩阵乘法即可。
题目的大意就是给你一张平面图,你可以对任何边进行染色,要使得最终得到的图中每个环上被染色的边数的奇偶性与这个环内包含的面的个数的奇偶性相同。输出任意染色方案即可。
这道题看似复杂,但仔细分析首先可以发现,对于任何一个环,只要其内部的每个面都满足题目要求的条件,则这个环一定是满足条件的。因此问题变为要使得该平面图的每个面上被染色的边数是奇数。注意到假设我们已经求出了一组解,则改变任意一条边的染色与否之后,我们可以顺次沿着面找到一条到达平面图边界面的路径,依次改变这些路径上边的染色与否,则其还是一组可行解。于是我们可以很简单的求出平面图的对偶图,并在对偶图上逐条边进行染色,每次染色进行深度优先搜索即可得到答案。
题目意思很简单,给出整数N,求出满足1<=a<b<=N的整数对(a, b)满足a+b | a*b。
进行简单的分析可以发现,a、b需满足条件a=kx(x+y)、b=ky(x+y)。但为避免重复,需要约定gcd(x, y)=1或k是一个Square-free Integer。最终我的做法是枚举x和y,求出满足条件的Square-free Integer的个数。但即使经过优化,速度仍然不够快。最后基本是猥琐的用C#卡时卡过去的……推荐大家看官方wiki……
题目的大意就是给你一棵带权树,你可以删除一些边,使得删除之后树中的每一个连通块满足该连通块中存在一个点到该连通块中的其他点的距离均不超过给定值d。求出删除边权值之和的最小值。
这个题目可以动态规划求解。记minCosts[i, j]表示以结点i为根的子树,且结点i与结点j之间不断开所需要删除边的最小权值和,则对于结点i的子结点,均需要决策是否和结点i断开。可记minSums[i]表示min{ minCosts[i, k] | 0 <= k < n },则有状态转移方程minCosts[i, j] = sum{ min(minCosts[k, j], minSums[j]+weight[i, j]) | k是i的子结点 }。最终删除边的最小权值和即为minSums[0]。
题目的大意就是给你一棵满二叉树,每个结点都有第一权值。定义一个结点的第二个权值:若为叶结点则为第一权值,否则为其第一权值乘以左右孩子第二权值的最大值。求根节点的第二权值。
显然直接递推或递归就可以了,但有个问题是中间结果要取模,因此不容易求出最大值。注意到整个过程中的运算都是乘积,因此直接取对数后加起来就好。