Thursday, June 1, 2017

Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

Problem Statement:
Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

Summary:
An integer array A of size n <= 5000 has entries which ranges from 1 to 5000. We pick disjoint segments of the array such that for each segment S:
1. If i in S, then any j s.t. a[j] == a[i] must also be in S
2. The score of S is computed as the XOR of its elements
Goal is to maximise the sum of scores of the chosen segments.

Solution:
I like this problem. This is solvable using a dynamic programming approach.


Suppose dp[i] is the maximum score we can get when we are only allowed to pick segments in A[0...i]. To find dp[i], we can:
1. Skip A[i]. So dp[i] is at least as good as dp[i-1].
2. Form a segment using A[i]. To do this we need to check a few things. First, say the smallest segment we can form (satisfying the above condition) is A[j...k] (i.e. j <= i && i <= k). Now, if k > i, then we cannot use A[i] to form the current segment, as we will be using elements beyond [0..i]. If k == i, then we know that dp[i] is at least as good as dp[j-1] + score of A[j...i].

With that, the implementation is quite straightforward.

Implementation:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <utility>
#include <cstring>
using namespace std;


int main(){
  int n;
  scanf("%d",&n);
  int a[5010];
  vector<pair<int,int>> b;
  for (int i = 0; i < n; ++i) {
    scanf("%d",&a[i]);
    b.push_back({a[i], i});
  }
  sort(b.begin(), b.end());
  int r[5010][2];
  int prev = b[0].second;
  for (int i = 1; i < n; ++i) {
    if (b[i].first == b[i-1].first) continue;
    int val = b[i-1].first;
    int last = b[i-1].second;
    r[val][0] = prev;
    r[val][1] = last;
    prev = b[i].second;
  }
  r[b.back().first][0] = prev;
  r[b.back().first][1] = b.back().second;
  int dp[5010];
  int mark[5010];
  for (int i = 0; i < n; ++i) {
    dp[i] = dp[i-1];
    bool can_choose = true;
    int last = i;
    int cur = 0;
    memset(mark, 0, sizeof(mark));
    for (int j = i; j >= last; --j) {
      if (r[a[j]][1] > i) {
        can_choose = false;
        break;
      }
      last = min(last, r[a[j]][0]);
      if (!mark[a[j]]) {
        cur ^= a[j];
        mark[a[j]] = 1;
      }
    }
    if (!can_choose) continue;
    dp[i] = max((last - 1 >= 0 ? dp[last-1] : 0) + cur, dp[i-1]);
  }
  printf("%d\n",dp[n-1]);
  return 0;
}

9 comments:

  1. "Great explanation! I struggled to grasp the segment formation condition at first, but your breakdown made it crystal clear. Thanks!"
    Heavy Duty Warehouse Racking delhiHeavy duty pallet rack delhi

    ReplyDelete
  2. "This problem highlights how dynamic programming can solve seemingly complex issues. Love the way you explained
    Warehouse Pallet Racking System Delhi
    two tier rack delhi

    ReplyDelete
  3. "I didn’t realize the XOR of elements could serve as a score. Very interesting approach!"
    Industrial Mezzanine Floor Delhi
    cable tray delhi

    ReplyDelete
  4. "The condition where was tricky for me to understand initially, but your write-up cleared it up perfectly. Well done
    Slotted Angle rack delhi
    Pallet storage rack india

    ReplyDelete
  5. "One thing I found challenging was ensuring disjoint segments meet all conditions. Your insights really helped clarify that!"
    Industrial Pallet Racks india
    Heavy Duty Rack

    ReplyDelete
  6. "5000-sized arrays and XOR scoring? Seems tough! Dynamic programming really is the key here."
    Heavy Duty Warehouse Racking
    Industrial Pallet Racks

    ReplyDelete
  7. "I appreciate the clarity in your explanation. I’ll implement the dp approach now and test it out on my own."
    Spare part storage rack india
    Heavy duty pallet rack noida

    ReplyDelete
  8. "Nice solution! A well-structured dynamic programming approach makes this problem much more manageable."
    Racking system noida
    Industrial Mezzanine Floor noida

    ReplyDelete
  9. "Thanks for sharing the intuition behind the solution. It’s always helpful to understand the reasoning rather than just the code."

    Mezzanine floor lucknow

    ReplyDelete