Codeforces 302(div1)

来源:互联网 发布:算法竞赛训练指南 pdf 编辑:程序博客网 时间:2024/05/16 12:38

A

定义状态f[i][j][k]如下:处理到第i行第j个人写了k个bug的方案数,为了实现O(1)的转移,我们每次只考虑第j个人的情况,要么他写下一行,转移
f[i+1][j][k+a[j]],要么推给后一个人,f[i][j+1][k]。初始化的时候f[0][1][0]=1,答案是f[m][n][0~b]

B

注意到m很小,所以我们用O(nm)的bfs处理出点对之间的距离,显然这道题要求的是一条从s1到t1和s2到t2的路径,并且使得它们共用的边数尽量多,然而我想了一会却没有什么思路,其实只要暴力枚举重合的路径就好了(从i到j),由于是无向图,所以有两种重合的情况,s1->i->j->t1、s2->i->j->t2和s1->i->j->t1、s2->j->i->t2.在if前多打一个else查了半天

C

看到数据范围应该就知道是状压DP了,而且只要修改过的位就不会互相冲突(n<26),想了一下状态的表示方式,如果按照位来考虑意义不太明显,所以按照每个字符串是否合法来设计状态。接下来我被复杂度坑到了,事实上这题O(2^n*n*m)就可以过了,我想省掉一个m,所以在转移的时候就有些不知所措。
考虑对每一位进行转移,要么把这一位改掉,要么就把和这一位重复的所有字符串都用最小花费改掉(预处理),这样转移就很正确了。

D

本来想用f[i][0/1]表示状态,但其实不用,考虑每条边,如果是坏边,那么子树里的所有边都要是好边,所以转移就是g[p]*=g[v]+1.其实这题主要的坑点在于换根,我一开始直接用除法逆元然后WA10,这是遇到除0的情况了(所以除法不能乱用啊),解决的方法是对于每个点,维护他儿子g数组的前缀积和后缀积。
这里还有个问题,比如现在的根是v,它的fa是u,那么g[u]就要改成去掉v以后的方案数.这道题看似很简单,只有两遍dfs,但要考虑除以0,所以对于我还是有些难度的。

清明假期还是被我浪过去了,不过发现了《知行合一王阳明》这本好书,感觉还是值得读和思考的。

0 0
原创粉丝点击