Monday, January 14, 2019

[UVa] 10069 - Distinct Subsequences

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 10069 - Distinct Subsequences
Source            : UVA Online Judge
Category          : Dynamic Programing, Big Integer Library
Algorithm         : Dynamic Programing
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll           long long int  
  6.   
  7. struct Bigint  
  8. {  
  9.       string a;  
  10.       int sign;  
  11.   
  12.       Bigint() {}  
  13.       Bigint(string b)  
  14.       {  
  15.             (*this) = b;  
  16.       }  
  17.       int size()  
  18.       {  
  19.             return a.size();  
  20.       }  
  21.       Bigint inverseSign()  
  22.       {  
  23.             sign *= -1;  
  24.             return (*this);  
  25.       }  
  26.       Bigint normalize(int newSign)  
  27.       {  
  28.             sign = newSign;  
  29.             for (int i = a.size() - 1; i > 0 && a[i] == '0'; i--) a.erase(a.begin() + i);  
  30.             if (a.size() == 1 && a[0] == '0') sign = 1;  
  31.             return (*this);  
  32.       }  
  33.       void operator = (string b)  
  34.       {  
  35.             a = b[0] == '-' ? b.substr(1) : b;  
  36.             reverse( a.begin(), a.end() );  
  37.             this->normalize( b[0] == '-' ? -1 : 1 );  
  38.       }  
  39.       bool operator < (const Bigint &b) const  
  40.       {  
  41.             if (a.size() != b.a.size()) return a.size() < b.a.size();  
  42.             for (int i = a.size() - 1; i >= 0; i--) if(a[i] != b.a[i]) return a[i] < b.a[i];  
  43.             return false;  
  44.       }  
  45.       Bigint operator + (Bigint b)  
  46.       {  
  47.             if (sign != b.sign) return (*this) - b.inverseSign();  
  48.             Bigint c;  
  49.             for (int i = 0, carry = 0; i < (int)a.size() || i < (int)b.size() || carry; i++)  
  50.             {  
  51.                   carry += (i < (int)a.size() ? a[i] - 48 : 0) + (i < (int)b.a.size() ? b.a[i] - 48 : 0);  
  52.                   c.a += (carry % 10 + 48);  
  53.                   carry /= 10;  
  54.             }  
  55.             return c.normalize(sign);  
  56.       }  
  57.       Bigint operator - (Bigint b)  
  58.       {  
  59.             if (sign != b.sign) return (*this) + b.inverseSign();  
  60.             if ((*this) < b) return (b - (*this)).inverseSign();  
  61.             Bigint c;  
  62.             for (int i = 0, borrow = 0; i < (int)a.size(); i++)  
  63.             {  
  64.                   borrow = a[i] - borrow - (i < b.size() ? b.a[i] : 48);  
  65.                   c.a += borrow >= 0 ? borrow + 48 : borrow + 58;  
  66.                   borrow = borrow >= 0 ? 0 : 1;  
  67.             }  
  68.             return c.normalize(sign);  
  69.       }  
  70.       Bigint operator * (Bigint b)  
  71.       {  
  72.             Bigint c("0");  
  73.             for (int i = 0, k = a[i]; i < (int)a.size(); i++, k = a[i])  
  74.             {  
  75.                   while(k-- - 48) c = c + b;  
  76.                   b.a.insert(b.a.begin(), '0');  
  77.             }  
  78.             return c.normalize(sign * b.sign);  
  79.       }  
  80.       Bigint operator / (Bigint b)  
  81.       {  
  82.             if (b.size() == 1 && b.a[0] == '0') b.a[0] /= (b.a[0] - 48);  
  83.             Bigint c("0"), d;  
  84.             for (int j = 0; j < (int)a.size(); j++) d.a += "0";  
  85.             int dSign = sign * b.sign; b.sign = 1;  
  86.             for (int i = a.size() - 1; i >= 0; i--)  
  87.             {  
  88.                   c.a.insert(c.a.begin(), '0');  
  89.                   c = c + a.substr(i, 1);  
  90.                   while (!(c < b)) c = c - b, d.a[i]++;  
  91.             }  
  92.             return d.normalize(dSign);  
  93.       }  
  94.       Bigint operator % (Bigint b)  
  95.       {  
  96.             if (b.size() == 1 && b.a[0] == '0') b.a[0] /= (b.a[0] - 48);  
  97.             Bigint c("0");  
  98.             int cSign = sign * b.sign; b.sign = 1;  
  99.             for (int i = a.size() - 1; i >= 0; i--)  
  100.             {  
  101.                   c.a.insert(c.a.begin(), '0');  
  102.                   c = c + a.substr(i, 1);  
  103.                   while(!(c < b)) c = c - b;  
  104.             }  
  105.             return c.normalize(cSign);  
  106.       }  
  107.       void print()  
  108.       {  
  109.             if (sign == -1) putchar('-');  
  110.             for (int i = a.size() - 1; i >= 0; i--) putchar(a[i]);  
  111.       }  
  112. };  
  113.   
  114. Bigint dp[10000+5][100+5];  
  115. bool memoize[10000+5][100+5];  
  116.   
  117. string x, z;  
  118. int lenx, lenz;  
  119.   
  120. inline Bigint solve(int i, int j)  
  121. {  
  122.       if (j >= lenz) return Bigint("1");  
  123.       if (i >= lenx) return Bigint("0");  
  124.       Bigint &ret = dp[i][j];  
  125.       bool &mem = memoize[i][j];  
  126.       if (mem) return ret;  
  127.       mem = 1;  
  128.       Bigint sum = Bigint("0");  
  129.       if (x[i] != z[j]) sum = solve(i+1, j);  
  130.       else sum = solve(i+1, j+1) + solve(i+1, j);  
  131.       return ret = sum;  
  132. }  
  133.   
  134. int main()  
  135. {  
  136.       int tc;  
  137.       cin >> tc;  
  138.       for (int tcase = 1; tcase <= tc; tcase++)  
  139.       {  
  140.             cin >> x >> z;  
  141.             lenx = x.size();  
  142.             lenz = z.size();  
  143.             memset(memoize, 0, sizeof memoize);  
  144.             Bigint ans = solve(0, 0);  
  145.             ans.print();  
  146.             cout << endl;  
  147.       }  
  148. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.