2017.1.13训练总结

来源:互联网 发布:推广淘宝优惠券挣钱 编辑:程序博客网 时间:2024/05/17 16:14

Problem 0

给出一个长度为n的序列a[1..n],将其变成序列b[1..n]的代价为ni=1|a[i]b[i]|,要使b[1..n]成为一个不下降序列,问最小的代价
1n104

Solution

这道题和之前做过的一道题很像,我的做法是用splay维护dp的数组,打了二十多分钟,还挺顺的。

Problem 1

要求动态维护两个01背包问题,第一个要求不同编号的物品视为不同物品,第二个要求同样大小的物品视为相同的物品。
所有的数据均在10000以内

Solution

由于是记数类问题,于是我们可以往生成函数那方面想。
首先对于第一个问题:不同编号的物品视为不同物品
考虑生成函数,对于加入一个大小为p的物品,显然,我们将多项式乘上(1+xp)
利用以下伪代码:

for i = MAX --> p     f[i]<--f[i]+f[i-p]

对于删除一个大小为p的物品,就是说我们要除以(1+xp)
考虑前者的代码,我们如何能够逆着做这样的操作,对于一个f[i],假设f[1..i-1]已经是除掉之后的结果,那么只需要减去f[i-p]
伪代码如下:

for i = p --> MAX    f[i]<--f[i]-f[i-p]

对于第二种问题:大小相同的物品视为同样的物品
假设有n种物品,第i种物品大小为p[i],数量为cnt[i]
那么我们的生成函数就是Πni=1cntij=0xj×pi
观察后面的式子,等比数列求和一下得到:Πni=11x(cnti+1)×pi1xpi
于是我们插入一个数大概是乘上一个1x(cnti+1)×pi1xcnti×pi
删除就直接反过来就好了
那么这个要怎样做,我们观察式子,发现乘上与除以的都是这样的形式:1xt
而在第一种问题中我们的是乘以和除以1+xt的形式
那么我们只要将加减号反过来就好了
最后就可以用O(n)的时间来维护一个修改
总的时间复杂度是O(n2)

Problem 2

平面直角坐标系中,有n个点,一个可行的建筑是指,有一个中心(整点,不一定是n个点之中的点),有若干个对角线分别平行于x轴和y轴且定点是n个点之中的点的四边形以这个中心为对角线交点,并且四边形各不相交,一个建筑的指数是指四边形的个数。求最大的建筑指数,最大建筑指数的中心点个数,最大建筑的个数。

Solution

首先考虑第一个要求的答案:最大的建筑指数。
先离散化,然后我们可以用扫描线加线段树来做。
按x轴扫描,然后对于该x上每两个相邻点之间,我们可以直接知道上下的点个数的影响,问题就是左右的点个数的影响,这个用线段树维护,由于只有n个点,那么每次扫到一个点时就将它加到左边,然后更改线段树上的值,那么求第一个答案,就只需要在相邻两个点之间查询一个最大值就好了,对于一个原来的点为中心的情况,我们可以直接计算。
然后同时处理第二个和第三个答案:中心个数和建筑个数
类似对第一个答案的处理方法,我们同样使用扫描线和线段树。
与上面不同的是,我们线段树维护了y轴一个区间内左右较小值是否大于等于ans1,如果是那么还有一个维护用于求第三个答案的组合数的和。那么对于两个相邻点之间,同样可以知道上下的点个数的影响,于是我们就可以直接算,对于点为中心,类似。
思路挺显然的,但是打的时候要注意常数,好多人因为常数问题过不去 ,大概就是扫描线不要扫太多次了,然后其实第二次的扫描中是可以用树状数组的,还有线段树的要注意一下。

真~总结

好了这里才开始扯总结,晚上这么晚打总结也是没谁了。
今天主要出现的问题是前面浪费了好多时间,一开始做第一题时看着很眼熟,大概推了一下以为是直接贪心就过去了,然后第二题看到70分部分分就直接认定要先敲完70分,第三题看完之后很快就想到了正解,感觉不是很麻烦,然后开始敲第二题,由于一开始用了multiset,然后没有注意到erase会把所有为这个值的元素都删除掉,然后错了一会没找出来。
最后开始打第一题时只剩下一个半钟了,然后发现自己想错了,最后还是想到了splay的做法,很快打完,但是大数据过不了,打了对拍之后,发现有一个下标写错了。
只剩下很少时间,匆匆打完最后一题三十分就收尾了。
接下来的训练里还是要抓紧一下时间,不要浪费太多时间了。

0 0