কম্পিউটার

C++ এ ন্যূনতম পার্সিং ট্রি খুঁজে বের করার প্রোগ্রাম


ধরুন আমাদের কাছে অনন্য এবং সাজানো সংখ্যার একটি তালিকা রয়েছে যা একটি স্ট্রিংয়ে ব্রেকপয়েন্টগুলিকে উপস্থাপন করে। আমরা এই নিয়মগুলি থেকে একটি গাছ তৈরি করতে চাই -

  • এমন নোড আছে যেগুলির একটি মান (a, b) আছে যেখানে a এবং b ব্রেকপয়েন্ট। এর মানে হল স্ট্রিং এর মধ্যে সূচক [a, b] থেকে নোড বিস্তৃত।

  • রুট নোড প্রতিটি ব্রেকপয়েন্ট জুড়ে বিস্তৃত। (পুরো স্ট্রিং)।

  • একটি নোডের বাম এবং ডান সন্তানের স্প্যানগুলি ক্রমানুসারে, সংলগ্ন এবং প্যারেন্ট নোডের স্প্যান ধারণ করে৷

  • ব্রেকপয়েন্টে 'a'-এর লিফ নোডের সূচক ব্রেকপয়েন্টে 'b'-এর সূচকের আগে 1।

গাছের প্রতিটি নোডের জন্য b - a এর যোগফল হিসাবে একটি গাছের মূল্য নির্ধারণ করা হয়। আমাদের লক্ষ্য হল একটি সম্ভাব্য গাছের সম্ভাব্য সর্বনিম্ন মূল্য নির্ধারণ করা।

সুতরাং, যদি ইনপুট ব্রেকপয়েন্টের মত হয় =[1, 4, 7, 12], তাহলে আউটপুট হবে 28।

এটি সমাধান করতে, আমরা এই পদক্ষেপগুলি অনুসরণ করব -

  • n :=ইনপুট অ্যারে ব্রেকপয়েন্টের আকার

  • যদি n <=1 হয়, তাহলে −

    • রিটার্ন 0

  • যদি n 2 এর সমান হয়, তাহলে −

    • রিটার্ন ব্রেকপয়েন্ট[1] - ব্রেকপয়েন্ট[0]

  • একটি অ্যারে সংজ্ঞায়িত করুন p[n - 1]

  • আরম্ভ করার জন্য i :=0, যখন i

    • p[i] :=ব্রেকপয়েন্ট[i + 1]

  • একটি অ্যারে পূর্ব[n]

    সংজ্ঞায়িত করুন
  • আরম্ভ করার জন্য i :=1, যখন i

    • pre[i] :=pre[i - 1] + p[i - 1]

  • একটি 2D অ্যারে dp[n, n] সংজ্ঞায়িত করুন এবং অসীম সহ কলামগুলি শুরু করুন৷

  • একটি 2D অ্যারে op[n, n]

    সংজ্ঞায়িত করুন
  • আরম্ভ করার জন্য i :=1, যখন i

    • dp[i,i] :=p[i - 1], op[i,i] :=i

  • শুরু করার জন্য len :=2, যখন len

    • আরম্ভ করার জন্য i :=1, যখন i + len - 1

      • j :=i + len - 1

      • idx :=i

      • আরম্ভ করার জন্য k :=সর্বাধিক (i, op[i,j-1]), যখন k <সর্বনিম্ন (j - 1, op[i + 1, j]), আপডেট করুন (k 1 দ্বারা বৃদ্ধি করুন), করবেন −

        • খরচ :=dp[i, k] + dp[k + 1, j]

        • যদি খরচ হয়

          • idx :=k

          • dp[i, j] :=খরচ

      • op[i, j] :=idx

      • dp[i, j] :=dp[i, j] + pre[j] - pre[i - 1]

  • রিটার্ন dp[1, n - 1]

উদাহরণ

আরো ভালোভাবে বোঝার জন্য আসুন নিচের বাস্তবায়ন দেখি -

#include <bits/stdc++.h>
using namespace std;
int solve(vector<int>& breakpoints) {
   int n = breakpoints.size();
   if (n <= 1) return 0;
   if (n == 2) return breakpoints[1] - breakpoints[0];
      vector<int> p(n - 1);
   for (int i = 0; i < n - 1; ++i) p[i] = breakpoints[i + 1] - breakpoints[i];
      vector<int> pre(n);
   for (int i = 1; i < n; ++i) pre[i] = pre[i - 1] + p[i - 1];
      vector<vector<int>> dp(n, vector<int>(n, INT_MAX));
      vector<vector<int>> op(n, vector<int>(n));
   for (int i = 1; i < n; ++i) dp[i][i] = p[i - 1], op[i][i] = i;
   for (int len = 2; len < n; ++len) {
      for (int i = 1; i + len - 1 < n; ++i) {
         int j = i + len - 1;
         int idx = i;
         for (int k = max(i, op[i][j - 1]); k <= min(j - 1, op[i + 1][j]); ++k) {
            int cost = dp[i][k] + dp[k + 1][j];
            if (cost < dp[i][j]) {
               idx = k;
               dp[i][j] = cost;
            }
         }
         op[i][j] = idx;
         dp[i][j] += pre[j] - pre[i - 1];
      }
   }
   return dp[1][n - 1];
}
int main(){
   vector<int> breakpoints = {1, 4, 7, 12};
   cout << solve(breakpoints) << endl;
   return 0;
}

ইনপুট

{1, 4, 7, 12}

আউটপুট

28

  1. C++ এ একটি লাইনের মধ্যবিন্দু খুঁজে বের করার জন্য প্রোগ্রাম

  2. C++ এ ত্রিভুজের সেন্ট্রোয়েড খুঁজে বের করার প্রোগ্রাম

  3. C++ এ সমান্তরালগ্রামের ক্ষেত্রফল বের করার প্রোগ্রাম

  4. C++ এ একটি গাছের সর্বোচ্চ গভীরতা বা উচ্চতা খুঁজে বের করার জন্য একটি প্রোগ্রাম লিখুন