[算法]拷贝粘贴可得到最大字符串长度

题目:如果只能使用复制和粘贴功能,给定任意初始字符串s和操作步数N,求经过N次操作之后可以获得的字符串的最大长度。假定复制可以复制当前任意长度的字符串。

例:s="abc",如果N为2,可以通过一次复制一次粘贴得到"abcabc",长度为6;如果N为3,可以通过一次复制,两次粘贴得到"abcabcabc",长度为9,可以通过一次复制,一次粘贴,再一次复制,但是因为没有粘贴,所以得到的是"abcabc",长度为6,后者不是最佳方案。

分析:N次操作必然是由前面的N-k次操作得到的,因此一种直观的想法就是使用动态规划来解决这个问题,关键是如何定义递归公式。一种做法是穷举所有从第N-k次操作到第N次的所有可能。

定义f(n)是第n次操作之后所得最大字符串长度,则利用穷举的方法f(n)=max {enumerate(f(n-k)->f(n))},这种做法比起直接穷举,没有任何改善,都是2^N复杂度。

我们可以以拷贝的时机作为切分和递归。定义操作c为复制,p为粘贴,当我们考察从n-k次操作到n此操作时,可以将一些情形进行递归。例如n-5到n,可以有多种操作:ccccc ccccp cccpp .... ppppp,我们发现其中一些操作是明显不是最优解法,那就是连续的复制,完全可以把连续复制中后面的复制改成粘贴,可以得到更好的解法。于是我们排除了很多序列。此外,我们认为一个有效的操作是从c开始的,如果一个操作序列从p开始,这种情况的结果取决于上一个c是什么时候开始的,这种情况的序列讨论,需要把上个c起始的序列长度进行考虑。比如5次操作全是p,上个c位于两个字符之前,这种情况的讨论应该把上个c也放进来,讨论7次操作的情况。基于这两个原因考虑,就只剩下了这几种情况:

cpcpc cpcpp cppcp cpppc cpppp

并且,如果最后一个操作符是c(这种情况下,c已经是整个序列的最后一步,因为我们考虑的是从N-5到N的情况),如果把最后一个操作改成p,可以有更长的序列,因此结尾是c的也可以都去掉,只剩下cpcpp cppcp cpppp。而前两者会分别先到达N-3和N-2,这两种情况会在k=2和3的时候进行比较,因此可以不放在k=5的情况考虑,于是我们得到
f(n)=max{k*f(n-k)} k=2...N
f(0)=len_init

f(1)=len_init //只有一次拷贝,还没来得及粘贴

于是复杂度从2^n变成了n^2

能不能更好?

通过上面的递推公式,我们可以这么理解这个问题,对于N次操作,我们需要对N进行任意长度的切分,每个的长度为wi,最终的长度就是所有wi的乘积,即

Σwi=N

obj=∏wi

由均值不等式(几何平均数不大于算数平均数,当且仅当所有数相等时取等号)可知,当所有wi都相等时,取得最大值。最大值为g(w)=w^(N/w),这个极值是多少?让我们回忆一下我们的高等数学,这种类型的极值,应该先求ln(g(w))的极值

ln(g(w))=ln w^(N/w)=N/w * ln w

对其求导得到ln'(g(w))=(1-ln w)/ w^2。过程自行推导。

于是w=e(自然对数的底)时取的极值。鉴于导数左正右负,因此ln(g(w))先单调递增,后单调递减,在w=e处有极大值。

然而,w的取值范围是正整数,所以,w只可能在2或者3处取得最大值,g(w)=w^(N/w)=(w^(1/w))^N。

w=2时,g(w)=(2^(1/2))^N=(√2)^N=1.414^N;

w=3时,g(w)=(3^(1/3))^N=(³√3)^N=1.442^N.

于是我们只要不断执行cpp就能得到最长序列,然而我们还得考虑一些边界条件,如果N不是3的倍数怎么办?当然我们需要用2补齐,或者浪费一次操作。如果余数是2,自然的用2补齐就好了(也可以考虑变成cpppp的情况,但是不是最优的),但是如果余数是1呢?我们就浪费一次操作吗?一种替代方式是减少一个cpp,变成两个cp,即对于cppc的情况,可以变成cpcp,这样长度从×3倍就变成了×4倍。另外一种考虑是直接把最后一个c变成p,同样也是×4。

于是这个问题就在O(1)时间内得到了解决。

这个问题又让我想起了方格从左上到右下的路径数问题,果然数学才是解决问题的性能优化利器。

请原谅我的公式的杂乱排版。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值