codeforces Educational Round 16 E. Generate a String

来源:互联网 发布:i like it what is it 编辑:程序博客网 时间:2024/06/14 01:13

题目链接

分析:

乍一看这道题感觉dp不能做,然后跑图论。spfa和dijkstra跑的话可能会复杂度太大。
实际上这道题dp可以做的,需要仔细想一下。

对于每个dp[i], 有三种转移方法dp[i]=min(dp[i1]+x,dp[i+1]+x,dp[i/2]+y)

先讨论偶数:偶数不可能从dp[i + 1]转移过来。这样想:i + 1作为一个奇数,只可能从i和i + 2转移过来,如果是前者,那么dp[i] < dp[i + 1], 与偶数从dp[i + 1]转移的前提dp[i] > dp[i + 1]矛盾;如果是后者,那么可以确定的一点就是dp[i + 1]的转移没有经过dp[i],这样一定存在一次翻倍。那么dp[i]的转移就是需要在一次翻倍的前提下再有字母的删除,花费是y+kx,这样一定比dp[i]从dp[i/2]转移只有一次y来得大,这也不可能。所以,讨论下来,dp[i]=min(dp[i1]+x,dp[i/2]+y)
再讨论奇数:奇数只可能从dp[i - 1]和dp[i +1]转移过来。如果dp[i]从dp[i + 1]转移,那么i+1作为一个偶数,一定只可能从dp[(i+1)/2)转移过来。为什么呢?如果dp[i+1]从dp[i]转移,那么dp[i] < dp[i + 1],就与dp[i]从dp[i +1]转移的前提dp[i] > dp[i + 1]矛盾,所以不可能。于是总结一下奇数的转移方程 dp[i]=min(dp[i1]+x,dp[i/2+1]+y+x)
然后就是O(N)的计算了。


没写代码,就不贴了

0 0