Algorithm 无法理解dp解决方案

Algorithm 无法理解dp解决方案,algorithm,dynamic-programming,Algorithm,Dynamic Programming,问题如下: for(i = 1; i <= n; i++) dp[i] = (dp[i-1] + p[i-1]) * p[i]; for(i = 1; i <= n; i++) ans+=2 * dp[i] + p[i]; Lazer Tag由一个小组游戏组成,在整个游戏中,你会被分配固定数量的子弹(通常称为激光射击)。对目标敌人的每一次右击都会给你一分 考虑一下你的一系列命中和未命中,它们可以用“x”和“o”表示,其中“o”表示命中,“x”表示未命中。假设该

问题如下:

for(i = 1; i <= n; i++)
    dp[i] = (dp[i-1] + p[i-1]) * p[i];   
for(i = 1; i <= n; i++)
    ans+=2 * dp[i] + p[i];
Lazer Tag由一个小组游戏组成,在整个游戏中,你会被分配固定数量的子弹(通常称为激光射击)。对目标敌人的每一次右击都会给你一分

考虑一下你的一系列命中和未命中,它们可以用“x”和“o”表示,其中“o”表示命中,“x”表示未命中。假设该系列的形式为“xxxooxxooxxo”,那么您的最终得分将等于
3^2+2^2+1^2
,即将整个游戏中每个最大连续点击数的平方相加

正确命中第j枪的概率(1≤J≤n) 是P(j)。更简单地说,在第j个回合的序列中得到“o”的概率是P(j)。您需要在回合结束时计算预期分数

我可以通过记忆理解这个问题的O(n^2)解,但这个问题需要O(n)解。我见过O(n)解,但我不能理解它。O(n)溶液如下所示:

for(i = 1; i <= n; i++)
    dp[i] = (dp[i-1] + p[i-1]) * p[i];   
for(i = 1; i <= n; i++)
    ans+=2 * dp[i] + p[i];

对于(i=1;i您可以用以下方式考虑评分:

  • 每击1分
  • 长度>1的每一次击球得分2分(多次重复得分)
  • 例如,一系列xxooox将得分:

  • +每个o的1个
  • +2为ooo
  • +第一个oo为2
  • +第二个oo为2
  • 分数=1*3+2*3=3+6=9分。(这与原来的分数方式相匹配,因为9=3*3)

    dp[i]计算在位置i处结束的长度大于1的预期运行次数

    因此,为了计算总的预期分数,我们需要求和2*dp[i](因为我们每次跑步都得到2分),再加上p[i]的总和,将每次命中得到1分的预期分数相加

    重复关系是因为在位置i处结束的长度大于1的预期运行次数为:

  • +1如果我们在位置i开始新的跑步,在i和i-1处命中(概率p[i]*p[i-1])
  • +dp[i-1]如果我们继续在位置i-1结束的跑步,得到另一次命中(概率p[i])

  • 您发布的解决方案不正确。这可能是您理解它时遇到困难的部分原因。只需对其进行模拟,将随机结果平均数百万次,您就会看到它给出了不同的结果。@Chill解决方案是正确的。这是问题链接[我给出的解决方案是公认的解决方案之一。那么,我的模拟肯定有问题。检查一下,如果你发现任何问题,请告诉我。
    “o”表示命中,“x”表示未命中
    为什么???@user2094963:这不是一个严肃的评论。我的意思是,99%的时间里,“x”表示“命中”和“o”意思是“小姐”。这就好像问题涉及到一个红绿灯,它用红色表示“走”,用绿色表示“停”:-P你能解释一下你是如何想出得分技巧的吗,即每0分1分,每0分+2分……我是dp新手,想知道如何处理这样的问题。非常有见地的彼得,我想知道你是如何注意到这一点的!我想这更像是一个数学问题,而不是普通的dp技巧。(我想我可能曾经在某个项目中看到过类似的问题。)@user2094963洞察更多的是关于以一种奇怪的方式计算二次函数,这种方式可以修改为概率递归。对于这个特定的问题,这绝对是一种非常酷和聪明的解决方案,但是你不需要理解它来解决一般的DP问题。@rrenaud这个问题能在O(n)时间内以任何其他方式解决吗?