बड़ी संख्या में उपप्रकारों के साथ गतिशील प्रोग्रामिंग। इसलिए मैं इंटरव्यू स्ट्रीट से इस समस्या को हल करने की कोशिश कर रहा हूं:
ग्रिड चलना (स्कोर 50 अंक)
आप स्थिति ( x 1 , x 2 , … , x N ) पर एक आयामी ग्रिड में स्थित हैं । ग्रिड के आयाम हैं ( D 1 , D 2 , … , D N )। एक चरण में, आप में से किसी एक में आगे या पीछे एक कदम चल सकते हैं आयाम। (इसलिए हमेशा संभव विभिन्न चालें हैं)। कितने तरीकों से आप ले सकते हैंएक्स मैं एक्स मैं ≤ 0 एक्स मैं > डी मैंऐसे कदम जो आप किसी भी बिंदु पर ग्रिड को नहीं छोड़ते हैं? यदि आप किसी भी , या तो या लिए ग्रिड ।
मेरा पहला प्रयास इस पुनरावर्ती समाधान था:
def number_of_ways(steps, starting_point):
global n, dimensions, mem
#print steps, starting_point
if (steps, tuple(starting_point)) in mem:
return mem[(steps, tuple(starting_point))]
val = 0
if steps == 0:
val = 1
else:
for i in range(0, n):
tuple_copy = starting_point[:]
tuple_copy[i] += 1
if tuple_copy[i] <= dimensions[i]:
val += number_of_ways(steps - 1, tuple_copy)
tuple_copy = starting_point[:]
tuple_copy[i] -= 1
if tuple_copy[i] > 0:
val += number_of_ways(steps - 1, tuple_copy)
mem[(steps, tuple(starting_point))] = val
return val
बड़ा आश्चर्य: यह स्मृति की कमी के कारण बड़ी संख्या में चरणों और / या आयामों के लिए विफल रहता है।
इसलिए अगला कदम डायनामिक प्रोग्रामिंग का उपयोग करके मेरे समाधान में सुधार करना है। लेकिन शुरू करने से पहले, मैं दृष्टिकोण के साथ एक बड़ी समस्या देख रहा हूं। तर्क starting_point
एक है -tuple, जहां के रूप में बड़ा है । तो वास्तव में, समारोह हो सकता है number_of_ways(steps, x1, x2, x3, ... x10)
के साथ ।
पाठ्यपुस्तकों में मैंने जो गतिशील प्रोग्रामिंग समस्याएं देखीं, उनमें लगभग सभी में दो चर हैं, ताकि केवल दो आयामी मैट्रिक्स की आवश्यकता हो। इस मामले में, एक दस-आयामी मैट्रिक्स की आवश्यकता होगी। तो कुल कोशिकाएं।
अपडेट करें
पीटर शोर के सुझावों का उपयोग करना, और कुछ मामूली सुधार करना, विशेष रूप से फ़ंक्शन में स्थिति का ट्रैक रखने की आवश्यकता है , और केवल दो सेट ए और बी में आयामों को विभाजित करने के अलावा, विभाजन को पुनरावर्ती रूप से करना, प्रभावी ढंग से उपयोग करना एक आधार मामले तक पहुँचने के लिए, जहां केवल एक आयाम सेट में होता है, तब तक फूट डालो और जीतो विधि।
मैं निम्नलिखित कार्यान्वयन के साथ आया, जिसने अधिकतम निष्पादन समय के नीचे सभी परीक्षण पास किए:
def ways(di, offset, steps):
global mem, dimensions
if steps in mem[di] and offset in mem[di][steps]:
return mem[di][steps][offset]
val = 0
if steps == 0:
val = 1
else:
if offset - 1 >= 1:
val += ways(di, offset - 1, steps - 1)
if offset + 1 <= dimensions[di]:
val += ways(di, offset + 1, steps - 1)
mem[di][steps][offset] = val
return val
def set_ways(left, right, steps):
# must create t1, t2, t3 .. ti for steps
global mem_set, mem, starting_point
#print left, right
#sleep(2)
if (left, right) in mem_set and steps in mem_set[(left, right)]:
return mem_set[(left, right)][steps]
if right - left == 1:
#print 'getting steps for', left, steps, starting_point[left]
#print 'got ', mem[left][steps][starting_point[left]], 'steps'
return mem[left][steps][starting_point[left]]
#return ways(left, starting_point[left], steps)
val = 0
split_point = left + (right - left) / 2
for i in xrange(steps + 1):
t1 = i
t2 = steps - i
mix_factor = fact[steps] / (fact[t1] * fact[t2])
#print "mix_factor = %d, dimension: %d - %d steps, dimension %d - %d steps" % (mix_factor, left, t1, split_point, t2)
val += mix_factor * set_ways(left, split_point, t1) * set_ways(split_point, right, t2)
mem_set[(left, right)][steps] = val
return val
import sys
from time import sleep, time
fact = {}
fact[0] = 1
start = time()
accum = 1
for k in xrange(1, 300+1):
accum *= k
fact[k] = accum
#print 'fact_time', time() - start
data = sys.stdin.readlines()
num_tests = int(data.pop(0))
for ignore in xrange(0, num_tests):
n_and_steps = data.pop(0)
n, steps = map(lambda x: int(x), n_and_steps.split())
starting_point = map(lambda x: int(x), data.pop(0).split())
dimensions = map(lambda x: int(x), data.pop(0).split())
mem = {}
for di in xrange(n):
mem[di] = {}
for i in xrange(steps + 1):
mem[di][i] = {}
ways(di, starting_point[di], i)
start = time()
#print 'mem vector is done'
mem_set = {}
for i in xrange(n + 1):
for j in xrange(n + 1):
mem_set[(i, j)] = {}
answer = set_ways(0, n, steps)
#print answer
print answer % 1000000007
#print time() - start
mem[]
शब्दकोश को भरकर सभी उपलब्ध सिस्टम मेमोरी को समाप्त कर देता है । और मेरे जवाब की सफाई के लिए धन्यवाद। LaTeX से बहुत परिचित नहीं हैं, लेकिन अगली बार एक प्रयास करेंगे।