Problem
玩一个捡金币游戏,现有N个金币从高空落下,玩家控制一辆小车左右开动捡金币(在x轴上开动,起初玩家在x=0处)。给出每个金币落地的时刻T[i] 和 落地的位置P[i],保证不会有两个金币同时落地。但小车只能装不超过3个金币,且小车速度随装载金币数量而变,速度=金币数量+1。玩家可以控制小车返回原点,返回原点时金币瞬间清空,玩家需要把所有的金币都运输到原点。问,玩家是否可以把所有金币都运回原点?如果可以,最小总距离是多少?如果不可以,第一个导致不可以的金币是哪一个?
Limits
Time Limit(ms): 8000
Memory Limit(MB): 65
N: 40
T[i]: [1, 50000],int
P[i]: [1, 100],int
Solution
很有意思的一道题,用dp来做。设dp[i][j]表示第 i 个金币捡到后小车有 j 个金币,dp[i][1]由dp[i-1][1],dp[i-1][2],dp[i-1][3]转移而来,dp[i][2]由dp[i-1][1]转移而来,dp[i][3]由dp[i-1][2]转移而来。若dp[n][j](j=1,2,3)存在,则可以把所有金币运回原点。
More
关键在于,玩家无法在小于T[i]时刻捡到第 i 个金币,捡到金币马上就走是最明智的,因此,若第 i 个金币能捡到,现只需判断当前到第 i+1 个金币的时间是否超过T[i+1]-T[i]即可。换句话说,在dp方程里不需要考虑时间因素。
if(当前可以从第i个金币到达第i+1个金币) dp[i][1]=min(dp[i][1],dp[i-1][j]+dis)(j=1,2,3)
if(当前可以从第i个金币到达第i+1个金币) dp[i][2]=min(dp[i][2],dp[i-1][1]+dis)
if(当前可以从第i个金币到达第i+1个金币) dp[i][3]=min(dp[i][3],dp[i-1][2]+dis)
最后,若dp[n][j](j=1,2,3)存在,则可以把所有金币运回原点,取dp[n][j](j=1,2,3)的最小值即可;否则不可把所有金币运回原点,找到第一个导致不可的金币即可。
Complexity
Time Complexity: O(N)
Memory Complexity: O(N*3)
Source
Code