2017.3.18【NOIP提高组】模拟赛B组

来源:互联网 发布:央企比民企好 知乎 编辑:程序博客网 时间:2024/05/06 07:52

这次比赛很恶心。比赛打得很辣鸡,但是改题进度还不错。很久没写过题解了23333~每次都很难改完题(改完了没时间写)今天信息课利用这个时间写一下。


T1:

题目大意:给你一个数列a1,a2,a3....an,可以循环移动k位ak,ak+1....an-1,a0,a1,....ak-1,当有一个序列(包括移动后)的前缀和每一项都不小于0,问有多少个这样的序列。

60分:

自然我们可以枚举这一个序列,判断即可。

100分:

根据题目,我们可以把a数组复制一次,变成a1,a2,a3....an,a1,a2,a3....an-1,长度为2n-1。

对此维护一个前缀和,设为pre。

那么当前假设选这个序列的l~l+n-1(l≤n),那么这个序列每一项的前缀和就是pre[i]-pre[l-1],i=l+1~l+n-1

看看有没有一项是小于0的,我们只需要找一个最小的pre[i],如果min(pre[i]-pre[l-1])<0那么不符合,反之,既然最小的都符合,那么当然就符合了。

找一个最小的min(pre[i]),可以用优先队列,线段树,RMQ,堆,推荐RMQ。


T2:

题目大意:小pp有q元,问小pp是否可以坚持到第m-1天。规则:第0天每瓶矿泉水都喝一次,之后每隔ai天就要再喝一瓶i种类矿泉水,价格为ci。每天可以喝一瓶或者不喝,在钱允许的情况下。

50分:

考试的时候并没有打,虽然很简单,只需要递归枚举喝或者不喝就好了。

考试没打主要是看不懂题目,╮(╯▽╰)╭

100分:

既然用递归打得题目,我们自然可以想到用动态规划。

设f[time,i,j,k,l]表示第time天,第1种水隔i天就要再喝,依次列推。若n不足4,那么多余的位置自然不鸟。

我们考虑怎么转移?

考虑几个问题:

1、是从前一天转移而来的吗?

2、从哪个状态(i,j,k,l,下同)转移而来?

3、当天的状态可以通过前一天的状态搞过来吗?


对于1,是显然的

对于2,我们要枚举上一次的状态

对于3,我们要分成几种情况


枚举上一次的状态,每个i,j,k,l都减一(注意n不够的就不减),然后判断0的个数,记为ans

若ans>1,舍去。因为一天不可能喝两种及以上的矿泉水

若ans=1,对那一个为0的进行喝水的处理,转移

若ans=0,可以选择喝其中一个,或者不喝。


转移自行思考。

提示:i,j,k,l因为不确定选几个,所以可以用递归实现。


T3:

题目大意:给你n个宽为1,长为ai(i≤n)的长方形,让你水平拼在一起,问最大的周长是什么?

60分:

可以用递归枚举顺序,然后判断即可。

100分:

对于一个题目这样的图形,我们可以分成2部分

一个部分是上和下,上是n,下也是n,所以就是2n

另一个部分就是剩余的边,这个就是我们需要考虑的。

有递归,就容易想到DP。

我们考虑f[i,s]表示你上一次选了i,当前状态是s(二进制)的第二部分的最大值。(不包括i的右边那部分)

当前的f[i,s]必定由f[k,kk]推出来(k为上上次选的,kk为上次的状态),显然,知道kk,i可以退出s

kk的符合条件:k出现过,i没有出现过

动态规划即可。

方案数同样如此


T4:

题目大意:给一堆数A1,A2....An,要你求出a[i]<a[k]<a[j](i<j<k)的数对(i,j,k)有多少个。

40分:

显然,三重循环即可。

100分:

显然,直接求出a[i]<a[k]<a[j](i<j<k)是十分困难的,不过可以通过另外的一种方式求出。

①a[i]<a[j]<a[k]&a[i]<a[k]<a[j](i<j<k)

②a[i]<a[j]<a[k] (i<j<k)

显然,①-②即为题目所求


考虑如果求①

你当前枚举一个数i,表示①式中的i,设右边有s个大于ai的数,则当前i选定时,这样的数对有k*(k-1)/2个。

设①式总和为ans,那么Ans就是上面的k*(k-1)/2的总和。

k可以用线段树,树状数组维护。


考虑求②

那么,你枚举一个j,表示②中的j,那么,同上,设左边有x个小于aj的,右边有y个大于aj的

结果即为x*y的总和,记作Ans1


那么题目所求,即为ans-ans1

同样可以用线段树维护上面的

说多了,就是线段树!


1 0
原创粉丝点击