这就是问题:
有个正在参加粉丝见面会的演员,他试图向排成一排的粉丝们免费拥抱。他从位置0开始,左右有球迷。他们的位置由负数和pos数(例如-3、5等)表示。他的球迷从拥抱中获得的“效用”(经济学)从某个数字开始(例如10),并且每走1步便减少1。演员想找到一种算法,以最大程度地提高粉丝们的效用。
例如,风扇在pos 2、4、6(初始效用为10)处可获得的最大效用为8 + 6 +4。
风扇数量N最多可以达到100,初始效用M最多可以达到10000(不能为负)。粉丝的位置在-10000到10000之间。
考虑到初始效用,风扇数量和风扇位置,请使用伪代码帮助解决此问题。
我莫名其妙地想到了解决它的方法。
答案 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,第二,第三,第四...直到第十。