Friday, March 29, 2019

[Codeforces] C. Choosing Balls

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : C. Choosing Balls
Source            : Codeforces
Category          : Dynamic Programing, STL
Algorithm         : DP, Hash Tables with PBDS
Verdict           : Accepted
Hash Tables with Policy Based Data Structure Tutorial : https://codeforces.com/blog/entry/60737
Without Hash Tables : 2214 ms
  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define pll              pair <ll, ll>  
  6.   
  7. typedef long long int        ll;  
  8.   
  9. static const int maxn = 1e5 + 5;  
  10. static const ll  inf  = 1e18;  
  11.   
  12. int n, q;  
  13. ll value[maxn], color[maxn], dp[maxn], curMax[maxn];  
  14.   
  15. int main()  
  16. {  
  17.       ios_base::sync_with_stdio(false);  
  18.       cin.tie(nullptr);  
  19.       cout << fixed << setprecision(15);  
  20.       #ifndef ONLINE_JUDGE  
  21.             freopen("in.txt""r", stdin);  
  22.       #endif // ONLINE_JUDGE  
  23.   
  24.       cin >> n >> q;  
  25.       for (int i = 1; i <= n; i++) cin >> value[i];  
  26.       for (int i = 1; i <= n; i++) cin >> color[i];  
  27.       while (q--)  
  28.       {  
  29.             ll a, b;  
  30.             cin >> a >> b;  
  31.             for (int i = 1; i <= n; i++)  
  32.             {  
  33.                   dp[i] = -inf;  
  34.                   curMax[ color[i] ] = -inf;  
  35.             }  
  36.             pll mx1 = pll(0LL, 1e5 + 5);  
  37.             pll mx2 = pll(0LL, 1e5 + 4);  
  38.             /** 
  39.             dp[j] = Maximum value we can obtain from position 1 to j (Subsequence) 
  40.             curMax[j] = Latest Maximum value using color j 
  41.             mx1 = {Maximum value, color} 
  42.             mx2 = {Maximum value, color} 
  43.             mx1.color != mx2.color 
  44.             **/  
  45.             for (int j = 1; j <= n; j++)  
  46.             {  
  47.                   if (curMax[ color[j] ] != -inf) // previous color == current color  
  48.                   {  
  49.                         dp[j] = max(dp[j], curMax[ color[j] ] + a * value[j]);  
  50.                   }  
  51.                   if (color[j] != mx1.second) // previous color != current color  
  52.                   {  
  53.                         dp[j] = max(dp[j], mx1.first + b * value[j]);  
  54.                   }  
  55.                   else  
  56.                   {  
  57.                         dp[j] = max(dp[j], mx2.first + b * value[j]);  
  58.                   }  
  59.                   if (dp[j] > mx1.first) // update mx1 and mx2  
  60.                   {  
  61.                         if (color[j] == mx1.second)  
  62.                         {  
  63.                               mx1 = pll(dp[j], color[j]);  
  64.                         }  
  65.                         else  
  66.                         {  
  67.                               mx2 = mx1;  
  68.                               mx1 = pll(dp[j], color[j]);  
  69.                         }  
  70.                   }  
  71.                   else if (dp[j] > mx2.first && color[j] != mx1.second)  
  72.                   {  
  73.                         mx2 = pll(dp[j], color[j]);  
  74.                   }  
  75.                   curMax[ color[j] ] = max(curMax[ color[j] ], dp[j]);  
  76.             }  
  77.             cout << mx1.first << '\n';  
  78.       }  
  79. }  

With Hash Tables : 3026 ms
  1. #include "bits/stdc++.h"  
  2. #include "ext/pb_ds/assoc_container.hpp"  
  3. #include "ext/pb_ds/tree_policy.hpp"  
  4.   
  5. using namespace std;  
  6. using namespace __gnu_pbds;  
  7.   
  8. #define pll              pair <ll, ll>  
  9.   
  10. typedef long long int        ll;  
  11. template <typename T> using HashTable = cc_hash_table <T, T, hash <T> >;  
  12.   
  13. static const int maxn = 1e5 + 5;  
  14. static const ll  inf  = 1e18;  
  15.   
  16.   
  17. int n, q;  
  18. ll value[maxn], color[maxn], dp[maxn];  
  19.   
  20. int main()  
  21. {  
  22.       ios_base::sync_with_stdio(false);  
  23.       cin.tie(nullptr);  
  24.       cout << fixed << setprecision(15);  
  25.       #ifndef ONLINE_JUDGE  
  26.             freopen("in.txt""r", stdin);  
  27.       #endif // ONLINE_JUDGE  
  28.   
  29.       cin >> n >> q;  
  30.       for (int i = 1; i <= n; i++) cin >> value[i];  
  31.       for (int i = 1; i <= n; i++) cin >> color[i];  
  32.       HashTable <ll> curMax;  
  33.       for (int i = 1; i <= n; i++) curMax[ color[i] ] = -inf;  
  34.       while (q--)  
  35.       {  
  36.             ll a, b;  
  37.             cin >> a >> b;  
  38.             for (int i = 1; i <= n; i++)  
  39.             {  
  40.                   dp[i] = -inf;  
  41.                   curMax[ color[i] ] = -inf;  
  42.             }  
  43.             pll mx1 = pll(0LL, 1e5 + 5);  
  44.             pll mx2 = pll(0LL, 1e5 + 4);  
  45.             /** 
  46.             dp[j] = Maximum value we can obtain from position 1 to j (Subsequence) 
  47.             curMax[j] = Latest Maximum value using color j 
  48.             mx1 = {Maximum value, color} 
  49.             mx2 = {Maximum value, color} 
  50.             mx1.color != mx2.color 
  51.             **/  
  52.             for (int j = 1; j <= n; j++)  
  53.             {  
  54.                   if (curMax[ color[j] ] != -inf) // previous color == current color  
  55.                   {  
  56.                         dp[j] = max(dp[j], curMax[ color[j] ] + a * value[j]);  
  57.                   }  
  58.                   if (color[j] != mx1.second) // previous color != current color  
  59.                   {  
  60.                         dp[j] = max(dp[j], mx1.first + b * value[j]);  
  61.                   }  
  62.                   else  
  63.                   {  
  64.                         dp[j] = max(dp[j], mx2.first + b * value[j]);  
  65.                   }  
  66.                   if (dp[j] > mx1.first) // update mx1 and mx2  
  67.                   {  
  68.                         if (color[j] == mx1.second)  
  69.                         {  
  70.                               mx1 = pll(dp[j], color[j]);  
  71.                         }  
  72.                         else  
  73.                         {  
  74.                               mx2 = mx1;  
  75.                               mx1 = pll(dp[j], color[j]);  
  76.                         }  
  77.                   }  
  78.                   else if (dp[j] > mx2.first && color[j] != mx1.second)  
  79.                   {  
  80.                         mx2 = pll(dp[j], color[j]);  
  81.                   }  
  82.                   curMax[ color[j] ] = max(curMax[ color[j] ], dp[j]);  
  83.             }  
  84.             cout << mx1.first << '\n';  
  85.       }  
  86. }