T1
这题感觉是这套题中最坑的一题了。比赛时用了01背包,时间超限得了50分。后来听说是转换多重背包,转完后还是50分(oAo)
正解:
因为虽然N,M范围很大,但仔细一看Ti和Vi都是≤10的,所以我们可以先用一个二位数组记录每种情况的个数,之后再把每一种背包都拆分成若干份,使得这若干份小背包通过组合,可以组合出1~背包数中的每一种可能(这一段要理解好)
假设一种背包的数量为X
则X可以拆分成2^0+2^1+……+2^log(x)
如果拆分完X还有剩余,则最后一项的值是剩下的数
例如:
假设X为15
那么17=1+2+4+8+2
之后把这些数进行01背包,就可以算出最后的答案。
T2
这道题是要求从左上角走到右下角所经过的数字的积末尾的0的数量最小,果断DP。
如果一个数的末尾有0,那么这个数可以拆分成(某数*10)而10又等于2*5。
所以一个数末尾的0的数量=min(2的数量,5的数量)
所以我们只要把输入的数分解成2和5,把2和5的数量记录下来,之后进行一次二维DP就OK了。
T3
这道题再之前的普及组出现过,只是最后结果的取余不同。
可以处(da)理(biao)n≤5的情况,之后用递推就可以算出最后结果。
递推式:f[i,j]=f[i-1,j]+f[i,j-1]+f[i-1,j-i](好像是这样吧)
在此谴责直接复制粘贴的某些同学(不包括我)
T4
这题再比赛时神奇的做(shui)到了100分(= =)
这题用O(n3)的算法得30分,O(n2)的算法也只能得50分,因此我们还要进一步优化。
我们先从30分的方法想起。
三重循环枚举3个点,再判断是否构成直角三角形并且直角边平行于坐标轴。
时间复杂度O(n3)
接着想50分。
我们可以先以行为第一关键字,以列为第二关键字快排,之后三重循环枚举。
首先先枚举两个点,并且这两个点都在同一条直线上时在枚举第三个点,之后累加答案,如果不在同一直线就直接跳出第二重循环。
时间复杂度 近似O(n2)
之后我们再从50分的方法推到100分。
50分的方法是三重循环,我们要想办法把它降到二重。
因为两条直角边都必须平行于坐标轴,所以第三个点的位置肯定在前两个点中的一个所在的那一列。例如:
+
|\
| \
| \
+----+
如图,第三个点只能在那两列上,所以我们只要先把每一列上的点的数量记录下来,再把两列的点数相加在-2(减去原来的两个点),在加到答案里面就是最终答案了。
然而,这道题并没有这么简单。
再仔细看要求,“所有坐标不超过32位整数范围”这条就已经可以让空间炸上天了。
但是,我们可以再用一系列神(wei)奇(suo)的方法把数组压缩到1~N
接下来便是神(wei)奇(suo)的方法
首先我们先把输入的行和列记录好位置,之后用快排分开来排序。
假设排序后的行是这样的
原 数
坐 值
标
1 1
5 3
4 4
2 6
3 8
然后我们把数值压缩成如下
原 新
坐 数
标 值
1 1
5 2
4 3
2 4
3 5
如果有多个重复的数,就把它们赋成同一个值
然后再把压缩后的数值按照原来的顺序放回数组
1
4
5
3
2
然后把列也这样压缩,之后以行为第一关键字,列为第二关键字进行快排。
之后就枚举两个点,在累加两个点所在列的点数在-2,就是最终的答案。
这题感觉是这套题中最坑的一题了。比赛时用了01背包,时间超限得了50分。后来听说是转换多重背包,转完后还是50分(oAo)
正解:
因为虽然N,M范围很大,但仔细一看Ti和Vi都是≤10的,所以我们可以先用一个二位数组记录每种情况的个数,之后再把每一种背包都拆分成若干份,使得这若干份小背包通过组合,可以组合出1~背包数中的每一种可能(这一段要理解好)
假设一种背包的数量为X
则X可以拆分成2^0+2^1+……+2^log(x)
如果拆分完X还有剩余,则最后一项的值是剩下的数
例如:
假设X为15
那么17=1+2+4+8+2
之后把这些数进行01背包,就可以算出最后的答案。
T2
这道题是要求从左上角走到右下角所经过的数字的积末尾的0的数量最小,果断DP。
如果一个数的末尾有0,那么这个数可以拆分成(某数*10)而10又等于2*5。
所以一个数末尾的0的数量=min(2的数量,5的数量)
所以我们只要把输入的数分解成2和5,把2和5的数量记录下来,之后进行一次二维DP就OK了。
T3
这道题再之前的普及组出现过,只是最后结果的取余不同。
可以处(da)理(biao)n≤5的情况,之后用递推就可以算出最后结果。
递推式:f[i,j]=f[i-1,j]+f[i,j-1]+f[i-1,j-i](好像是这样吧)
在此谴责直接复制粘贴的某些同学(不包括我)
T4
这题再比赛时神奇的做(shui)到了100分(= =)
这题用O(n3)的算法得30分,O(n2)的算法也只能得50分,因此我们还要进一步优化。
我们先从30分的方法想起。
三重循环枚举3个点,再判断是否构成直角三角形并且直角边平行于坐标轴。
时间复杂度O(n3)
接着想50分。
我们可以先以行为第一关键字,以列为第二关键字快排,之后三重循环枚举。
首先先枚举两个点,并且这两个点都在同一条直线上时在枚举第三个点,之后累加答案,如果不在同一直线就直接跳出第二重循环。
时间复杂度 近似O(n2)
之后我们再从50分的方法推到100分。
50分的方法是三重循环,我们要想办法把它降到二重。
因为两条直角边都必须平行于坐标轴,所以第三个点的位置肯定在前两个点中的一个所在的那一列。例如:
+
|\
| \
| \
+----+
如图,第三个点只能在那两列上,所以我们只要先把每一列上的点的数量记录下来,再把两列的点数相加在-2(减去原来的两个点),在加到答案里面就是最终答案了。
然而,这道题并没有这么简单。
再仔细看要求,“所有坐标不超过32位整数范围”这条就已经可以让空间炸上天了。
但是,我们可以再用一系列神(wei)奇(suo)的方法把数组压缩到1~N
接下来便是神(wei)奇(suo)的方法
首先我们先把输入的行和列记录好位置,之后用快排分开来排序。
假设排序后的行是这样的
原 数
坐 值
标
1 1
5 3
4 4
2 6
3 8
然后我们把数值压缩成如下
原 新
坐 数
标 值
1 1
5 2
4 3
2 4
3 5
如果有多个重复的数,就把它们赋成同一个值
然后再把压缩后的数值按照原来的顺序放回数组
1
4
5
3
2
然后把列也这样压缩,之后以行为第一关键字,列为第二关键字进行快排。
之后就枚举两个点,在累加两个点所在列的点数在-2,就是最终的答案。