硬DP概率伪代码算法

时间:2019-01-02 17:57:49

标签: algorithm data-structures dynamic-programming

这就是问题:

有个正在参加粉丝见面会的演员,他试图向排成一排的粉丝们免费拥抱。他从位置0开始,左右有球迷。他们的位置由负数和pos数(例如-3、5等)表示。他的球迷从拥抱中获得的“效用”(经济学)从某个数字开始(例如10),并且每走1步便减少1。演员想找到一种算法,以最大程度地提高粉丝们的效用。

例如,风扇在pos 2、4、6(初始效用为10)处可获得的最大效用为8 + 6 +4。

风扇数量N最多可以达到100,初始效用M最多可以达到10000(不能为负)。粉丝的位置在-10000到10000之间。

考虑到初始效用,风扇数量和风扇位置,请使用伪代码帮助解决此问题。

我莫名其妙地想到了解决它的方法。

1 个答案:

答案 0 :(得分:1)

dp [r] [l] [b] [i] =您可以通过访问r作为最右边的风扇,l作为最左边的风扇,b来表示您是否位于最右边的风扇,从而获得最大实用程序或离开,我是剩下的工具。可能的状态数量为100 * 100 * 2 * 10000 = 200000000,应该可以在不到一秒钟的时间内解决。

伪代码:2中的粉丝分开,<0和> 0。

solve(left, right, atRight, utility):
    if left < 0 or right > totalFans or utility <= 0:
        return 0
    if dp[left][right][atRight][utility] != None:
        return dp[left][right][atRight][utility]        

    if atRight == true:
        dp[left][right][atRight][utility] = max(solve(left, right + 1, true, utility - distance(right, right + 1)), solve(left + 1, right, false, utility - distance(right, left + 1))) + utility
    else:
        dp[left][right][atRight][utility] = max(solve(left + 1, right, false, utility - distance(left, left + 1)), solve(left, right + 1, true, utility - distance(right + 1, left))) + utility

return dp[left][right][atRight][utility]



answer = max(solve(0, 1, true, initialUtility - distance(0, firstFan at dist > 0)), solve(1, 0, false, initialUtility - distance(0, firstFan at dist < 0)))

您基本上会尝试所有可能,状态是您所在的位置,已经拥抱的最右边的风扇,已经拥抱的最左边的风扇以及剩余的实用程序。如果最左边的风扇是10,则意味着您已经拥抱到最接近0的风扇,该位置在pos <0,第二,第三,第四...直到第十。