বিপুল সংখ্যক উপ-সমস্যা সহ গতিময় প্রোগ্রামিং। তাই আমি ইন্টারভিউ স্ট্রিট থেকে এই সমস্যাটি সমাধান করার চেষ্টা করছি:
গ্রিড ওয়াকিং (স্কোর 50 পয়েন্ট)
আপনি অবস্থানে একটি ডাইমেনশনাল গ্রিডে রয়েছেন । গ্রিডের মাত্রা )। এক ধাপে, আপনি যে কোনও মাত্রার মধ্যে এক ধাপ এগিয়ে বা পিছনে যেতে পারেন । (সুতরাং সর্বদা সম্ভাব্য বিভিন্ন পদক্ষেপ থাকে)। আপনি কতগুলি উপায়ে পদক্ষেপ নিতে পারেন যে আপনি কোনও পর্যায়ে গ্রিডটি ছাড়েন না? আপনি যে কোনো যদি গ্রিড ছেড়ে , হয় বা ।
আমার প্রথম চেষ্টাটি ছিল এই স্মৃতিযুক্ত পুনরাবৃত্ত সমাধান:
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, যেখানে যত বড় । সুতরাং প্রকৃতপক্ষে, ফাংশনটি সাথে থাকতে পারে ।n 10 1 ≤ x i ≤ 100number_of_ways(steps, x1, x2, x3, ... x10)
পাঠ্যপুস্তকগুলিতে আমি যে ডায়নামিক প্রোগ্রামিং সমস্যাগুলি দেখেছি সেগুলির প্রায় সকলেরই দ্বিগুণ ভেরিয়েবল রয়েছে, যাতে কেবলমাত্র দ্বি-মাত্রিক ম্যাট্রিক্সের প্রয়োজন হয়। এই ক্ষেত্রে, দশ-মাত্রিক ম্যাট্রিক্সের প্রয়োজন হবে। সুতরাং মোট কোষ।
ডায়নামিক প্রোগ্রামিং-এ 2-ডি ম্যাট্রিক্স সহ, পরবর্তী গণনার জন্য সাধারণত পূর্বের সারি গণনার প্রয়োজন হয়, তাই স্থানিক জটিলতা থেকে হ্রাস করে । আমি নিশ্চিত না যে এই ক্ষেত্রে আমি কীভাবে এটি করব। কোনও টেবিলটি দৃশ্যমান করা সম্ভব নয়, সুতরাং উপরের পুনরাবৃত্তি থেকে উত্তরটি সরাসরি আসতে হবে।
হালনাগাদ
পিটার শোরের পরামর্শগুলি ব্যবহার করে এবং কিছু ছোটখাটো সংশোধন করা, বিশেষত ফাংশনে অবস্থানের উপর নজর রাখার প্রয়োজন , এবং কেবল মাত্র দুটি সেট এ এবং বি বিভক্তকরণের পরিবর্তে বিভাজনকে কার্যকরভাবে ব্যবহার করে বিভাজন এবং বিজয় পদ্ধতি, একটি বেস কেস না পৌঁছানো পর্যন্ত যেখানে কেবলমাত্র একটি মাত্রা সেট থাকে।
আমি নিম্নলিখিত বাস্তবায়ন নিয়ে এসেছি, যা সর্বোচ্চ কার্যকরকরণের সময়ের নীচে সমস্ত পরীক্ষায় উত্তীর্ণ হয়েছিল:
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[]
। এবং আমার উত্তর পরিষ্কার করার জন্য আপনাকে ধন্যবাদ। ল্যাটেক্সের সাথে খুব বেশি পরিচিত না কিন্তু পরের বার চেষ্টা করবেন।