// DP solution: try all subsets of tools still available #include #include using namespace std; const int MAX = 300000; int T; int task[MAX]; // what tools are still available, current tool, task int memo[8][3][MAX+1]; int solve(int tools, int curr_tool, int task_i) { if (task_i >= T || !tools) { return 0; } int &ans = memo[tools][curr_tool][task_i]; if (ans >= 0) { return ans; } ans = 0; // try doing this task if (task[task_i] == curr_tool) { ans = max(ans, solve(tools, curr_tool, task_i+1) + 1); } // try skipping ans = max(ans, solve(tools, curr_tool, task_i+1)); // try dropping the tool int new_tools = tools - (1 << curr_tool); for (int i = 0; i < 3; i++) { if (new_tools & (1 << i)) { ans = max(ans, solve(new_tools, i, task_i)); } } return ans; } int main() { cin >> T; for (int i = 0; i < MAX; i++) { cin >> task[i]; } for (int i = 0; i < 8; i++) { for (int j = 0; j < 3; j++) { fill(memo[i][j], memo[i][j]+MAX+1, -1); } } int ans = 0; for (int i = 0; i < 3; i++) { ans = max(ans, solve(7, i, 0)); } cout << ans << endl; return 0; }