CF - An impassioned circulation of affection

Authors: Neo Wang, Qi Wang, Jesse Choe, Kevin Sheng

Official Editorial

Solution (Two Pointers)

Time Complexity: O(nq)\mathcal{O}(nq)

For each query we can keep a sliding window where no more than mm letters in the window are not cc.

Implementation

C++

#include <bits/stdc++.h>
using namespace std;
int main() {
int garland_len, query_num;
string garland;
cin >> garland_len >> garland >> query_num;
for (int i = 0; i < query_num; i++) {
int max_repaint;

Alternative Solution (Two Pointers with Prefix Sums)

Time Complexity: O(n(k+q))\mathcal{O}(n(k+q))

For each query we can use prefix sums to check the number of occurrences of a given letter cc and use two pointers to find the maximum Koyomity ending at a given pointer p2p2 from 0n0 \dots n.

C++

#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 1500;
int dp[26][MAX_N + 1];
int main() {
int garland_len;
string garland;

Alternative Solution (Dynamic Programming)

Warning!

Dynamic programming is a Gold topic.

Time Complexity: O(n2k+q)\mathcal{O}(n^2k + q)

We are performing up to 200000200\,000 queries, so it may be optimal to have some way to quickly precompute our answer in constant time.

We can use dynamic programming to cache such answers.

Define dp[i][j][k]\texttt{dp}[i][j][k] to be the best possible score of the first ii characters, with jj amount painted of character kk. Either two things can happen when we add an additional character.

  1. We append the character and paint an additional square.

    dp[i+1][j+1][k]=max(dp[i+1][j+1][k],dp[i][j][k]+1)\texttt{dp}[i+1][j+1][k] = \max(\texttt{dp}[i+1][j+1][k], \texttt{dp}[i][j][k] + 1)
  2. We append the character, but since it is the same as our previous character we get to "save" a paint.

    dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]+1)\texttt{dp}[i+1][j][k] = \max(\texttt{dp}[i+1][j][k], \texttt{dp}[i][j][k] + 1)

Since this only gives us the best possible score that ends with length ii, we can just take the current best and translate it using dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k])\texttt{dp}[i+1][j][k] = \max(\texttt{dp}[i+1][j][k], \texttt{dp}[i][j][k]).

Now, we can query the max painting score for any substring containing the first character. However, this is not required; we only have to query the optimal paintings with size nn (the full string) with dp[n][mi][ci]\texttt{dp}[n][m_i][c_i].

Implementation

C++

#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 1500;
int dp[MAX_N + 1][MAX_N + 1][26];
int garland[MAX_N + 1];
int main() {
int garland_len;

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!