货币兑换

首先这道题目,记得把题面看完,最后一句话是给了提示的。。。

肯定考虑DP嘛,但DP不太清楚怎么设置状态,而且不清楚一天到底交易多少次

我们先来解决第二个问题,由于这是一道可以被解决的题目,所以我们猜想交易的次数非常有限

根据题目最后的提示,某一天的开端,我们要么全部都是钱,要么全部都是股票

假设某一天的开端,我们全部都是钱,一共有IP这么多钱,那么我们可以选择不操作;如果选择操作,那么一定是全部买完。通过列方程不难得出,获得的股票B的数量是xB=IPAkRatek+bk,获得的股票A的数量是xA=Ratek×xB=RatekIPAkRatek+bk。如果我们选择再全部卖出,那么获得的钱为xAAk+xBBk=IP,与最开始的钱是一样的。综上,我们要么不操作,要么只操作一次,把所有钱都换成股票

假设某一天的开端,我们全部都是股票,假设有两种股票分别有xAxB这么多,我们可以选择不操作;如果操作,我们获得的钱是xAAk+xBBk,如果再全部买回来,我们有xB=xAAk+xBBkAkRatek+bkxA=Ratek×xB=Ratek(xAAk+xBBk)AkRatek+bk,发现跟最开始长得好像不一样,别慌,继续卖,我们发现又会获得相同的钱xAAk+xBBk。综上,我们要么不操作,要么操作一次全部卖出变成钱,要么操作两次变成比例不一样的股票(其实全变成钱之后就回到了上面一段所叙述的情况了)

但发现到这里还是没有什么办法DP,我们只是把每一天的操作局限在了两次以内,这个时候我们就先设置f[i]表示第i天能够获得的最多的钱,然后考虑如何DP下去

我们考虑当达到第i天的开始的时候,我们一定是要么全是钱,要么全是股票

对于第一种情况,有f[i]=f[i1](注意我们状态设置的是最多有多少钱,所以在第i天结束时,一定会全部转换成钱)

对于第二种情况,我们考虑这些股票是在什么时候交易过来的,也就是说上一次把所有钱变成股票是什么时候。我们枚举这个时候,假设这个时候是第j天,那么有f[i]=xjAi+yjBi,其中yj=f[j]AjRatej+Bj,xj=Ratejyj

出现了ij的乘积,感觉是斜率优化,但是又跟一般的斜率优化,不太一样,因为有两项乘积,别怕,我们这个时候随便提出某一项跟i有关的常量(注意一定要提取跟i有关的,因为当i固定的时候,这是常量),有f[i]=Bi(xjAiBi+yj),这个时候就是普通的斜率优化了,我们用李超线段树即可。但要注意这里的AiBi是实数,我们需要先离散化

最开始那一大堆数学分析可以帮助我们理解整个过程,而且蕴含的思想(一天不会交易很多次)在有些题目也是很重要的

update 2024.7.6

其实我们很想设出我们当前手上的券的数目,然而我们发现显然复杂度会爆炸,所以上面枚举的策略也是一种解决方法

update 2024.9.11

首先我们知道这是一道可以解决的题目,于是我们可以猜想每天的交易次数有限,所以有了上面一大堆数学分析帮助我们厘清过程;现在我们想将每天拥有的股票数量设在维度里面,但是股票的数量显然有可能是实数且复杂度会爆炸,所以不行,一般这种时候就是可行性转最优性,但是这里已经是最优性了,所以我们只能进行取舍,假设f[i]表示到了第i天最多拥有的钱数,于是有了上面的方法(相当于时间换空间了);列出来式子之后显然是化成普通的斜率优化的形式,但是现在发现xj,AiBi不一定递增,于是只能用CDQ分治/平衡树。但是题解给我们介绍了一种利用李超线段树优化的方法,显然对任意的斜率优化题目都适用,所以记住。然后看一下实数怎么离散化

posted @   最爱丁珰  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示