Advertisement
shamiul93

***1013 - Love Calculator

May 31st, 2017
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.91 KB | None | 0 0
  1. /**
  2. @author - Rumman BUET CSE'15
  3. Problem - 1013 - Love Calculator
  4.  
  5. concept - LCS , DP
  6.  
  7. শিক্ষাঃ
  8.  
  9. অনেক অনেক অনেক জোস প্রব্লেম । এবং আমার ঘাম ছুটে গেসে এটা করতে গিয়ে । সিম্পল আইডীয়া । ৮০০+ সল্ভ । মানে আসলে ফালতু প্রব্লেম । কিন্তু নতুন নতুন শিখতেসি বলে টাইম বেশি লাগলো ।
  10.  
  11. ১। ২ টা জিনিস চাইসে । -
  12.         1. The length of the shortest string that contains the names as subsequence.
  13.         2. Total number of unique shortest strings which contain the names as subsequence.
  14.  
  15.     ১ নাম্বারের জন্য ২ টা উপায় আছে । - প্রথমে LCS বের করে এরপরে                 =  s1 length + s2 length - LCS(s1,s2)
  16.     এটা গেলো একটা । আরেকটা আছে । - ডায়রেক্ট এমন কোন shortest string ডিপি দিয়ে জেনারেট করা , যাতে করে that contains the names as subsequence.
  17.  
  18.     এই সেকেন্ড উপায় টা লাভ জনক কারণ , এটা দিয়ে ২ নাম্বারের এন্সার দিতে পারাটা ইজি । এজন্য ২ নাম্বার ওয়েতেই সল্ভ করসি ।
  19.  
  20.  
  21. আসলে কি করসি ?
  22.  
  23. উঃ প্রথমে এমনে একটা এমন shortest string ডিপি দিয়ে জেনারেট করসি , যাতে করে that contains the names as subsequence.
  24. কেমনে ? প্রথমে  SeqLen অ্যারে এর প্রথম রো আর প্রথম কলাম যথাক্রমে রো নাম্বার আর কলাম নাম্বার দিয়ে ভরসি । এক কথায় , ইনক্রিজিং নাম্বার দিয়ে ভরসি ।
  25. কেন ? এর সিগ্নিফিকেন্স কি ?
  26.  
  27. সাপোজ , জাস্ট একটা স্ট্রিং নিসি । মানে s1 নিবো , কিন্তু s2 নিবো না । তাইলে লেংথ কতো হবে ? পুরাটাই আস্তে আসতে নিবো না ? হ্যাঁ । কারণ নাইলে তো আমি যে স্ট্রিং বানাবো তাতে আমার পুরা
  28. s1 স্ট্রিং টা থাকবে না ।
  29. সেম কাজ s2 এর জন্য । - এগুলা হলো বেস কেস ।
  30.  
  31. আচ্ছা , যদি এখন আর শুধু একটা না নেই , মানে বেস কেস ছাড়া অন্য কেস নেই তাইলে কি হবে ?
  32. যদি ২ টা অক্ষর সেইম হয় , তাইলে কর্ণ বরাবর উপরে যে সংখ্যা আছে তার সাথে ১ যোগ করে যোগফলই হবে লেংথ । এটা সোজা বুঝা যাবে ।
  33.  
  34. আর যদি  সেইম না হয় ? তাইলে যে দিক গেলে লেংথ মিনিমাম আসে সেটার সাথে ১ যোগ ।
  35. উঃ আচ্ছা ১ যোগ তো বুঝলাম । কারণ যেহেতু shortest string জেনারেট করতে চাইতেসি , যাতে করে that contains the names as subsequence. কাউকে
  36. তো বাদ দেয়া যাবে না । সবাইকেই থাকা লাগবে । কিন্তু মিনিমাম কেন ? আমরা lcs বের করার সময় তো ঠিকই ম্যাক্সিমাম নিতাম , তাইলে ?
  37.  
  38. * এখানে কারণ হলো , আমি এখানে lcs বা লংগেস্ট বের কতে চাইতেসি না । চাইতেসি শরটেস্ট স্ট্রিং বের করতে , যাতে করে সবাই থাকে । এজন্য -
  39.  
  40.             ১। মিনিমাম নিতে হবে , ২ । ১ যোগ করতে হবে সব ক্ষেত্রেই ।
  41.  
  42.  
  43.  
  44. ২য় পারটঃ
  45.  
  46. আচ্ছা । ওয়ে কেমনে বাইর করবো ?
  47. উঃ ওয়ে বাইর করতে হলে সবার বেইস কেইস হবে 1 . কেন ? কারণ হলো , ধরো তুমি কোন অক্ষরই নেও নাই , কিন্তু সেটাও কিন্তু একটা ওয়ে । আবার তুমি একটা স্ট্রিং টোটালি বাদ দিয়ে
  48. আরেকটা স্ট্রিং কে নিতেসো , প্রতি পারটে আসলে একটাই উপায় বা ওয়ে থাকবে । USSR - U , US , USS , USSR এরা প্রত্যেকেই আলাদা ওয়ে । এবং এদের প্রত্যেকেই ১ ভাবেই নেয়া যায় ।
  49.  
  50. আর অন্য সব কেইসে সহজ । নরমালি " কয়টা LCS পসিবল ?" - এই প্রশ্নের সাথে এই প্রশ্নের খুব বেশি পার্থক্য নাই । উপায় হলো  ,
  51. যদি দেখো যে ২ টা অক্ষর সেইম , তাইলে , জাস্ট কর্ণ বরাবর উপরের সংখ্যাই এখানে বসবে । কেন ? চিন্তা করে দেখো , ২ টা সমান হইলে ২ টাকে নিবো না । ১ টাকে নিবো । রাইট ???
  52. তার মানে আমার কাজ হলো যা ছিলো , তার শেষে একটা অক্ষর যোগ করে দেয়া । ওয়ে চেঞ্জ হইসে ? হয় নাই ।
  53.  
  54. আর যদি অক্ষর সেইম না হয় , তাইলে জাস্ট চিন্তা করো । ২ জনের লেংথে যেদিক গেলে লেংথ কম হয় সেদিকে যাইতে হবে না ? হ্যাঁ । সেদিকে যে ওয়ে পাবো সেদিকের ওয়েই হবে এন্সার ।
  55.  
  56. কিন্তু অক্ষর সেইম হইলো না , উপরে আর বামের লেংথ সেইম । তাইলে ২ দিকেই সমান লেংথ আসতেসে । সো , ২ দিকের ওয়ে যোগ হয়ে সামনে প্রসীড করবো । এর চেয়ে বেশি আপাতত ব্যাখ্যা
  57. করার তেল নাই । বাকিটা মাথায় বুঝে নিলাম ।
  58.  
  59. */
  60.  
  61.  
  62.  
  63. // LightOJ always needs this format for sure..so I made a copy of it...
  64. #include <bits/stdc++.h>
  65. #include<vector>
  66. #define ll                                      long long int
  67. #define fi                                      freopen("in.txt", "r", stdin)
  68. #define fo                                      freopen("out.txt", "w", stdout)
  69. #define m0(a) memset(a , 0 , sizeof(a))
  70. #define m1(a) memset(a , -1 , sizeof(a))
  71.  
  72. #define mx 150000
  73. using namespace std;
  74. string s1, s2 ;
  75. ll len1, len2 ;
  76.  
  77. ll SeqLen[40][40] = {} ;
  78. ll SeqNum[40][40] = {} ;
  79.  
  80. ll Length()
  81. {
  82.     for(ll i = 0 ; i < 40 ; i++)
  83.     {
  84.         SeqLen[i][0] = i ;
  85.         SeqLen[0][i] = i ;
  86.     }
  87.  
  88.     for(ll i = 1 ; i <= len1 ; i++)
  89.     {
  90.         for(ll j = 1 ; j <= len2 ; j++)
  91.         {
  92.             if(s1[i-1] == s2[j-1])
  93.             {
  94.                 SeqLen[i][j] = 1 + SeqLen[i-1][j-1] ;
  95.             }
  96.             else
  97.             {
  98.                 SeqLen[i][j] = 1 + min(SeqLen[i-1][j], SeqLen[i][j-1]) ;
  99.             }
  100.         }
  101.     }
  102.  
  103.     return SeqLen[len1][len2] ;
  104. }
  105.  
  106. ll Number()
  107. {
  108.     for(ll i = 0 ; i < 40 ; i++)
  109.     {
  110.         SeqNum[i][0] = 1 ;
  111.         SeqNum[0][i] = 1 ;
  112.     }
  113.  
  114.     for(ll i = 1 ; i <= len1 ; i++)
  115.     {
  116.         for(ll j = 1 ; j <= len2 ; j++)
  117.         {
  118.             if(s1[i-1] == s2[j-1])
  119.             {
  120.                 SeqNum[i][j] = SeqNum[i-1][j-1] ;
  121.             }
  122.             else
  123.             {
  124.                 if(SeqLen[i-1][j] < SeqLen[i][j-1])
  125.                 {
  126.                     SeqNum[i][j] = SeqNum[i-1][j] ;
  127.                 }
  128.                 else if(SeqLen[i-1][j] > SeqLen[i][j-1])
  129.                 {
  130.                     SeqNum[i][j] = SeqNum[i][j-1] ;
  131.                 }
  132.                 else if(SeqLen[i-1][j] == SeqLen[i][j-1])
  133.                 {
  134.                     SeqNum[i][j] = SeqNum[i-1][j] + SeqNum[i][j-1] ;
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     return SeqNum[len1][len2] ;
  140. }
  141.  
  142. void print()
  143. {
  144.     for(int i = 0 ; i < len1+1 ; i++)
  145.     {
  146.         for(int j = 0 ; j < len2+1 ; j++)
  147.         {
  148.             cout << SeqLen[i][j] << " " ;
  149.         }
  150.         cout << endl ;
  151.     }
  152.     cout << endl ;
  153.     for(int i = 0 ; i < len1+1 ; i++)
  154.     {
  155.         for(int j = 0 ; j < len2+1 ; j++)
  156.         {
  157.             cout << SeqNum[i][j] << " " ;
  158.         }
  159.         cout << endl ;
  160.     }
  161. }
  162.  
  163.  
  164.  
  165. int main()
  166. {
  167. //    fi ;
  168. //    fo ;
  169.     ll T, t = 0 ;
  170.     scanf("%lld",&T) ;
  171.  
  172.     while(T--)
  173.     {
  174.         m1(SeqLen);
  175.         m1(SeqNum) ;
  176.  
  177.         t++ ;
  178.  
  179.         cin >> s1 >> s2 ;
  180.         len1 = s1.length() ;
  181.         len2 = s2.length() ;
  182.  
  183.         ll l, n ;
  184.  
  185.         l = Length() ;
  186.         n = Number() ;
  187.  
  188. //        print() ;
  189.  
  190.         printf("Case %lld: ",t) ;
  191.         printf("%lld %lld\n",l, n) ;
  192.  
  193.     }
  194.     return 0 ;
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement