Yuki 496 ワープクリスタル (給料日前編) ( DP )
No.496 ワープクリスタル (給料日前編) - yukicoder
題意:
你有 N 顆一次性的魔法石頭,第 i 顆可以幫你在 X 軸上 + X[ i ],Y 軸上 + Y[ i ],但花費魔力 C[ i ]。你現在在 ( 0, 0 ),你的目的地是 ( Gx, Gy )。另外一種移動方式是向上或向右一格,花費 F。問最少花費到達目的地。
制約:
0≤Gx,Gy≤100
0≤N≤50
1≤F≤200
0≤xi≤Gx, 0≤yi≤Gy, (xi,yi)≠(0,0)
1≤ci≤200
解法:
dp[ i ][ j ][ k ] : 已考慮前 i 顆石頭,現在在 ( j, k ),已形成的最小花費。
注意 N 可能為 0,這特判就行了。
時間 / 空間複雜度:
O( N * Gx * Gy )
from copy import deepcopy Gx, Gy, N, F = map( int, input().split() ) X = [] Y = [] C = [] for i in range( N ): x, y, c = map( int, input().split() ) X.append( x ) Y.append( y ) C.append( c ) if N == 0: exit( print( F * ( Gx + Gy ) ) ) INF = int( 1e15 ) dp = [ INF for i in range( Gy + 1 ) ] dp = [ deepcopy( dp ) for i in range( Gx + 1 ) ] dp = [ deepcopy( dp ) for i in range( N + 1 ) ] dp[ 0 ][ 0 ][ 0 ] = 0 for i in range( N ): for j in range( Gx + 1 ): for k in range( Gy + 1 ): dp[ i + 1 ][ j ][ k ] = min( dp[ i + 1 ][ j ][ k ], dp[ i ][ j ][ k ] ) if j + X[ i ] <= Gx and k + Y[ i ] <= Gy: dp[ i + 1 ][ j + X[ i ] ][ k + Y[ i ] ] = min( dp[ i + 1 ][ j + X[ i ] ][ k + Y[ i ] ], dp[ i ][ j ][ k ] + C[ i ] ) if j + 1 <= Gx: dp[ i ][ j + 1 ][ k ] = min( dp[ i ][ j + 1 ][ k ], dp[ i ][ j ][ k ] + F ) dp[ i + 1 ][ j + 1 ][ k ] = min( dp[ i + 1 ][ j + 1 ][ k ], dp[ i ][ j ][ k ] + F ) if k + 1 <= Gy: dp[ i ][ j ][ k + 1 ] = min( dp[ i ][ j ][ k + 1 ], dp[ i ][ j ][ k ] + F ) dp[ i + 1 ][ j ][ k + 1 ] = min( dp[ i + 1 ][ j ][ k + 1 ], dp[ i ][ j ][ k ] + F ) print( dp[ N ][ Gx ][ Gy ] )