20190818B组

20190818B组

T1:100(100)

赛时:

一看很像树形,于是就码了个树形dp,可是莫名得打挂了。

看了看数据不大,于是想贪心。

将点的能量需求做一个排序,从小到大。

然后看这个点是否能根节点达到。

能就将路径上边传递的能量减掉。

赛后:

贪心,每次选取能量需求最小的节点,扫描它到根节点的路径上的边的容量,看能否满足,如果能满足就把它到根节点的路径上的边的容量都减去它的需求即可。

本题如果把握不好贪心的正确性也可以写树状动规(多叉树,揹包转移),但是显然编程复杂度就上升了一个层次。

算法:

贪心&树形dp

T2:100(100)

赛时:

手玩了一下后发现,答案肯定在某个区间的右端点。

于是接下来就很简单了。

直接从小到大排序,然后扫一遍就AC了。

赛后:

很容易想到,最优解的E肯定是某个区间的端点!

所以我们把所有区间的左右端点取出,从小到大排序,扫描一遍。

维护一个变量sa,表示扫描到的值为p时,左端点大于p的所有区间的左端点之和;维护一个变量sp,表示扫描到的值为p时,p在左右端点之间的区间个数。那么此时可以封印一击得到的能量就是sa+sp*p。

扫描时遇到一个左端点,sa减去这个左端点,sp加一;遇到一个右端点,sp减一即可。

算法:

模拟

T3:20(0)

赛时:

这题看完题目后,一脸懵逼。

根本没有一点解题思路,但是题还是要做的在比赛里。

于是我就开始想骗分。

乱打了一波后,时间也不多了,可有调不出来。

于是就输出0加上去了。

赛后:

算法一:类比最长公共子序列的DP方法 (O(NM^2) 80分)

首先枚举B的M个循环同构串。F[i,j]表示A串前i个字符和B串前j个字符能否匹配。

如果a[i]=b[j],F[i,j]=F[i-1,j-1];

如果a[i]='*',F[i,j]=F[i-1,j] or F[i,j-1] or F[i-1,j-1]。

边界:F[0,0]=true,如果a[1]='*',F[1,0]=true,其余为false。

算法二:DP+RKhash (O(NM) 100分)

首先按'*'把A串分成几段,从前往后第i段给一个hash值i,这样的hash值最多有(N+1)/2个。

F[i,j]表示在B串的第i个位置之后,第一次出现hash值为j的串的位置。

把B串前M-1个字符复制一份接在B串后面,枚举起始位置1~M,然后利用F[i,j],依次向后找A串的那些段最早出现的位置,判断最后到达的位置和起始位置的差是否超过了M即可。但是要注意如果A串开头、结尾不是'*',要先把开头结尾处理掉。

本题数据不好做,可能我做的比较弱(本来就只有两个大点)。

 

算法:

dp+hash

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章