8.22

· · 个人记录

T1

题目大意:

给定若干个序列,第一个数是id,可以忽略,其余的数都按原始序列的顺序排列,求能不能找到原始序列。

原思路:

看每个位置出现过最多的数,如果有多个且次数都为1,那就不行,否则可以。

正解:

因为题目中说是否符合排序规则,就想到拓扑,除了第一和最后一个位子,其余的数都会往后面的一个数连一条单向边,判断是否可行就判断拓扑运行到的点的个数是否为n。

T2

题目大意:

给定一个图,每个点代表一个字母,求路径上出现次数最多的字母的数量的最大值,如果有环,输出-1。

原思路:

用并查集,但一个点有多个父亲没办法解决。

正解:

如果有环,输出-1就是明显的拓扑,找路径上出现次数最多的字母的数量就是dp。
dp[i][j]代表路径的最后节点为i,路径中字母j的个数。
初始:所有的dp[i][字母-'a']个数加一。
转移:拓扑枚举边时每次枚举每个字母,如果这个节点代表的字母和枚举的字母是一样的那就看dp[t][j]+1,dp[i][j]的最大值,不同就是dp[t][j],dp[i][j]的最大值。

T3

题目大意:

给定一棵树,每个节点有一个点权,求一个在子树内选取偶数个子节点的最大点权,根节点也可以。

原思路:

没有想到怎么写。

正解:

树形dp. dp[i][0]:以i为根节点,在这个子节点选偶数个数的最大点权。
dp[i][1]:以i为根节点,在这个子节点选奇数个数的最大点权。
转移: dp[x][0]就是偶数(这个点)配偶数(子节点),或奇数(这个点)配奇数(子节点)。
dp[x][1]就是偶数(这个点)配奇数(子节点),或奇数(这个点)配偶+数(子节点)。
每个节点的子节点枚举完后找dp[x][1],dp[x][0]+a[x]最大值,更新时要用没更新前的。

T4

题目大意:

给定一个数组,要求选取k个数,求这些数的乘积末尾连续零的个数最大值。

原思路:

dp每次更新找dp[i-1][j-1]*a[i]和dp[i][j]=dp[i-1][j]圆整度更大的。

正解:

要是后面零的个数,想到2*5是10,所以可以找所有数中的5和2的个数最小值所以dp[i][j]代表选i个数,5的个数为j,最大2的个数。
转移:枚举选取的个数和5的个数,在最大的dp[枚举的选取的个数-1][枚举的5的个数-这个数的5的个数]+2的个数,为了不影响更新时的数,从大往小遍历,最后找dp中最大的5的个数和2的个数中小的。