UVa 11368 - Nested Dolls

uvaর কিছু মজার প্রবলেমের ভিতর এইটা অন্যতম । প্রবলেমে বলসে যেঃ কিছু পুতুল আছে । সেই পুতুল গুলাকে একটার ভিতর আরেকটা ভরানো যায় । কিন্তু এই ভরানোর জন্য অবশ্যই দৈর্ঘ্য এবং প্রস্থ কম হইতে হবে । মানে যদি h1 w1 and h2 w2 দুইটা পুতুল হয় এবং h1 < h2 && w1 < w2 হয় তাহলে প্রথম পুতুলকে দ্বিতীয় পুতুলে ঢুকানো যাবে । ফলে দুইটা পুতুল কমে হয়ে যাবে একটা পুতুল । আমাকে বলতে হবে আমারা আমাদের চোখের সামনে(চোখের সামনে কথাটা প্রবলেমে লেখা নাই ।) মোট কয়টা পুতুল দেখতে পারব ? এই প্রবলেম সল্ভ করতে আমাদের মাথায় অনেক কিছু ঘুরতে পারে ! যেমন গ্রিডী আল্গো । কিন্তু একটু ভাল করে খেয়াল করলে দেখা যাবে যে এইটা একটা লিসের (LIS: Longest increasing subsequence) প্রবলেম । দেখা যাক ক্যামনেঃ আমরা একটা ইনপুটের কথা চিন্তা করি!ঃ

২০ ২০

১০ ১০

১০ ১০

৩০ ৩০ ২০ ২০ ১০ ১০ ১০ ১০

এইটা আমাদের ইনপুট ! একটু খেয়াল করলেই দেখা যাবে যে ৩০ ৩০ এর ভিতর ২০ ২০ কে ঢুকানো যায় । আবার ২০ ২০ এর ভিতর ১০ ১০ কে ঢুকানো যায় । তাহলে ৩০ ৩০ + ২০ ২০ + ১০ ১০ = ১ টা পুতুল !

আবার আরো একটা ২০ ২০ আছে ! এইটা আবার ধরতে পারে ১০ ১০ কে ! তাহলে আমারা পাই ২০ ২০ + ১০ ১০ = ১ টা পুতুল ! তাহলে দেখা যায় ঃ ৩০ ৩০ + ২০ ২০ + ১০ ১০ + ২০ ২০ + ১০ ১০ = ২ টা পুতুল ! আর অন্য পুতুল গুলাকে কারো ভিতর ঢুকানো যায় না ! তাহলে আমাদের পুতুল হবে এখন কয়টা ? মানে চোখের সামনে কয়টা পুতুল দেখতে পারব ? ৩০ ৩০, ২০ ২০, ১০ ১০ ,১০ ১০ = ৪ টা পুতুল !

এখন আমরা ক্যামনে প্রোগ্রাম করব এইটাকে ! ক্যামনে লিসে ফেলাব প্রবলেমটাকে ! দেখা যাকঃ আমরা হাইট ওয়াজ সর্ট করব । মানে প্রথমে যার হাইট বড় তাকে আগে নিব, এবং যার হাইট কম তাকে পরে । হাইট সমান হইলে যার প্রস্থ কম সে আগে আসবে , যার বেশি সে পরে যাবে ! তাহলে উপরের ইনপুটের আকার হবে এইরকমঃ

৩০ ৩০ ২০ ২০ ২০ ২০ ১০ ১০ ১০ ১০ ১০ ১০ ১০ ১০

এইবার আমরা যদি বাইনারি সার্চ চালাই তাহলেই তো হয়ে গেল আমদের আন্সার ! কিন্তু আমরা প্রতি পুতুলের জন্য সার্চ চালাব । কাজেই আমাদের কমপ্লেসিটি হবে nlogk. n= number of doll, k= number of elements in LIS array !

তাহলে আমরা কি পাই ? প্রথমে ৩০ ৩০ এর জন্য বড় উপাদান খুজব । দেখলাম নাই । তাহলে ৩০ ৩০ আমাদের লিস অ্যারের প্রথম উপাদান।

এইবার ২০ ২০ জন্য খুজব । দেখলাম যে ২০ ২০ এর জন্য ইমিডিয়েট বড় একটা উপাদান অ্যারেতে আছে । তা হল ৩০ ৩০ । তাহলে আমরা ৩০ ৩০ এর জায়গায় ২০ ২০ বসায় দেই । মানে ২০ ২০ কে ৩০ ৩০ এর ভিতর ঢুকে দিলাম ।

আবার ঠিক বড় উপাদান খুজব । দেখলাম যে সেইটা পাওয়া যায় নি । তাহলে আমরা আমাদের অ্যারে তে আরেকটা ডল নিব সেইটা হবে ২০ ২০ । সুতরাং অ্যারেতে পুতুল আছে ২ টা । ২০ ২০, ২০ ২০।

এইবার আমরা আবার খুজব । ১০ ১০ এর বড় উপাদান আরেতে আছে । কাজেই আমরা ১০ ১০ কে ২০ ২০ এর ভিতর ভরাব । তাহলে আমাদের অ্যারে হবে ১০ ১০, ২০ ২০ ।

আবার আমরা ১০ ১০ পাব এবং খুজব । তখন আমরা পাব আরেকটা ২০ ২০ । এর ভিতর ভরাব । আমাদের অ্যারে হবে ১০ ১০, ১০ ১০ ।

লক্ষ কর, আমাদের কিন্তু ভিজিবল পুতুল এখনও ২ টা । এইবার আমরা আরেকটা ১০ ১০ নিলাম । বড় কিছুই পাইলাম না । এইটাকে আরেতে ভরালাম । ১০ ১০ , ১০ ১০ , ১০ ১০। সেইম আরেকবার । অ্যারের উপাদান হবে ১০ ১০ , ১০ ১০ , ১০ ১০, ১০ ১০ । মোট পুতুল হইল কয়টা ? ৪ টা :) আমাদের আন্সার হইয়া গেসে ^_^ ।

প্রশ্ন হওয়া স্বাভাবিক আমি কেন অ্যারের h গুলাকে ডিসেন্ডিং এবং w গুলাকে আসেন্ডিং অর্ডারে সাজাইলাম । উত্তর সহজ । দেখ বলা হয়েছে যে আমাদের ডলকে অবশ্যই h1 < h2 && w1 < w2 হতে হবে । যদি আমি এইভাবে না সাজাইতাম তাহলে আমার অবস্থা এমন হইত যে মাঝে মাঝে ছোট প্রস্থের পুতুলের ভিতর বড় প্রস্থের পুতুল ভরাইতে হত । যা অসম্ভব ( not for AJ, buT for programmers : একটা উদাহরণ দেই ।

ধর আমার ইনপুট হইল এইরকমঃ

২০ ২০ ২০ ২১ ১০ ১০ ১০ ২১

আমরা সর্ট করলে কি পাব ?

২০ ২১ ২০ ২০ ১০ ২১ ১০ ১০ কিন্তু যদি w1 > w2 এইভাবে সট করতাম তাহলে পেতামঃ২০ ২১২০ ২০১০ ২১১০ ১০আমাদের অ্যারে হইত এই করমঃ ১০ ২১, ১০ ১০=২ টা পুতুল । উত্তর ভুল ^_^ :( প্রবলেম দেখার পর নিজে চেষ্টা কর, না বুঝলে আমার ইমপ্লিমেন্ট দেখতে পার । http://paste.ubuntu.com/10528195/