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

今天又垫底了。。。


T1:这题的方法十分巧妙,我当场没有想出来。

其实我们的目的就是要把n-1个数变成0,而剩下的那一个数变成2^k。换句话说,就是把n个数的二进制表示形式变成n-1个0,1个10...0,。那也就是要我们尽可能的多消掉1。

所以我们可以这样做:

先把n个数都化成二进制形式,然后我们先考虑把最后一位的1给消掉。因为这n个数的和为2^k,所以一定有偶数个数的二进制形式的末尾为1,所以我们可以把这些数两两组合,这样就可以把最后一位的1消掉,接下来的第二,第三位等同理。最终就可以求出一种方案。


总结:这题的本质就是找所有操作相同的地方,首先发现*2就是在二进制表示形式的末尾加上一个0,进而发现有偶数个末尾为1的数,从而解决问题。其实好像石子问题都是这样的。


T2:首先设f[i]表示第i个位置的答案,那么f[i]=min(f[j]+(i-j)*a[j]+b[i])(1<=j<i),这样只能拿50分,所以我们可以考虑队列优化。

首先,若有j<j'且a[j]>a[j']且f[j]+(i-j)*a[j]>f[j']+(i-j')*a[j'],那么j一定是不如j'优的。

所以,我们可以把有用的位置存下来,以后只需搜索这些位置就可以了,关键是怎么存?

假设当前已经算出f[i],我们要把i放入序列,并且要把不如i优的踢出序列,那么若序列中有一个j满足a[j]>a[i]或f[i]+(i-i)*a[i]>f[j]+(i-j)*a[j]也就是f[i]>f[j]+(i-j)*a[j],那么这个j是要被留下的。具体实现可以用两个数组互相滚动,这样可以快很多。


总结:比赛时爆0,这里总结一下对这类dp的优化。

若要用单调栈优化,那么一定要针对转移方程中所有不确定元素来建栈,不能只针对某一部分。比如这道题,应该针对f[j]+(i-j)*a[j]来建栈,而比赛时我只针对了a[i]来建栈。


T3:这题十分水,而比赛时我却因为文件输入输出打错而爆0。

正解就是把行纵坐标排个序,然后直接模拟就行了。注意:要用二分来查找。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值