Problem:
Score : 300 points

Problem Statement

There are N cubes stacked vertically on a desk.

You are given a string S of length N. The color of the i-th cube from the bottom is red if the i-th character in S is 0, and blue if that character is 1.

You can perform the following operation any number of times: choose a red cube and a blue cube that are adjacent, and remove them. Here, the cubes that were stacked on the removed cubes will fall down onto the object below them.

At most how many cubes can be removed?

Constraints

1 \leq N \leq 10^5

|S| = N

Each character in S is 0 or 1.

Input

Input is given from Standard Input in the following format:

S

Output

Print the maximum number of cubes that can be removed.

Sample Input 1

0011

Sample Output 1

4

All four cubes can be removed, by performing the operation as follows:

Remove the second and third cubes from the bottom. Then, the fourth cube drops onto the first cube.

Remove the first and second cubes from the bottom.

Sample Input 2

11011010001011

Sample Output 2

12

Sample Input 3

0

Sample Output 3

0

Solution in C++14 (Clang 3.8.0) (judge verdict: Time Limit Exceeded)

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <tuple>
#include <stdbool.h>
#include <bitset>
#include <string>

using namespace std;

// 置換場所検索用
std::vector<int> find_all(const std::string str, const std::string subStr) {
    std::vector<int> result;
 
    int subStrSize = subStr.size();
    int pos = str.find(subStr);
 
    while (pos != std::string::npos) {
        result.push_back(pos);
        pos = str.find(subStr, pos + subStrSize);
    }
 
    return result;
}

map<string, int> reduce_memo { {"", 0} , {"1", 0}, {"0", 0}, };
int reduce(const string str) {
    // メモしてある結果
    if (reduce_memo.count(str) > 0) {
        // cout << "[dbg] mem_ret result:" << reduce_memo[str] << " " << str << endl;
        return reduce_memo[str];
    }
    // 取り除けそうな場所を列挙
    auto targets = find_all(str, "01");
    auto targets2 = find_all(str, "10");
    targets.insert(targets.end(), targets2.begin(), targets2.end());
    // なければ終了
    if (targets.size() == 0) {
        return 0;
    } else {
        // あれば一番いいところを採用
        int max_index = -1;
        int max_result = -1;
        // cout << "[dbg] targets.size():" << targets.size() << endl;

        set<string> calced;
        for(const int index: targets) {
            string tmp(str);
            tmp.replace(index, 2, "");
            // すでにやった内容と一致している可能性があるので枝刈りする
            if(calced.count(tmp) > 0) {
                continue;
            }
            calced.insert(tmp);
            // いい結果を
            auto result = reduce(tmp) + 2;
            // cout << "\t[dbg] result:" << result << " " << str << " -> " << tmp << endl;
            if (max_result < result) {
                max_index = index;
                max_result = result;
            }
        }

        // 一番良い結果
        if (max_index < 0) {
            cout << "Not Implemented" << endl;
            return -1;
        }
        // メモって返す
        // cout << "[dbg] new_ret result:" << max_result << " " << str << endl;
        reduce_memo[str] = max_result;
        return max_result;
    }
}
int main(void) {
    string str;
    cin >> str;

    auto result = reduce(str);
    cout << result << endl;
    return 0;
}