Cod sursa(job #1741885)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 15 august 2016 13:40:34
Problema Elimin 2 Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <fstream>
#include <cmath>
#include <vector>
#include <iomanip>
#include <queue>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_set>
#include <set>
#include <map>
#include <unordered_map>
#include <stack>
#include <bitset>
using namespace std;

ifstream cin("elimin2.in");
ofstream cout("elimin2.out");

const int MAXN = 2005;

char s[1 + MAXN], answer[1 + MAXN];
short int dp[1 + MAXN][1 + MAXN];
short int Left[1 + MAXN][10], Right[1 + MAXN][10];
int leftPointer, rightPointer, length;

void Reconstitute(int leftIndex, int rightIndex, int first) {
    if (rightIndex - leftIndex <= 1)
        return;
    if (rightIndex - leftIndex == 2) {
        answer[leftPointer] = s[leftIndex + 1];
        return;
    }
    short int best = 0;
    for (int digit = 9; digit >= 0; digit--)
        best = max(best, dp[Right[leftIndex + 1][digit]][Left[rightIndex - 1][digit]]);
    for (int digit = 9; digit >= first; digit--)
        if (dp[Right[leftIndex + 1][digit]][Left[rightIndex - 1][digit]] == best) {
            if (first) {
                length = best;
                leftPointer = 0;
                rightPointer = length - 1;
            }
            answer[leftPointer] = answer[rightPointer] = digit + '0';
            leftPointer++;
            rightPointer--;
            Reconstitute(Right[leftIndex + 1][digit], Left[rightIndex - 1][digit], 0);
            break;
        }
}

int main() {
    cin >> s + 1;
    int n = strlen(s + 1);
    for (int i = 1; i <= n; i++)
        dp[i][i] = 1;
    for (int l = 2; l <= n; l++)
        for (int i = 1; i <= n - l + 1; i++) {
            int j = i + l - 1;
            dp[i][j] = max (short(dp[i + 1][j - 1] + 2 * (s[i] == s[j])), max(dp[i + 1][j], dp[i][j - 1]));
        }
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= 9; j++)
            Left[i][j] = Left[i - 1][j];
        Left[i][s[i] - '0'] = i;
    }
    for (int i = n; i >= 1; i--) {
        for (int j = 0; j <= 9; j++)
            Right[i][j] = Right[i + 1][j];;
        Right[i][s[i] - '0'] = i;
    }
    Reconstitute(0, n + 1, 1);
    cout << answer;
    return 0;
}