Cod sursa(job #1508975)

Utilizator atatomirTatomir Alex atatomir Data 23 octombrie 2015 12:36:46
Problema Elimin 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

#define pb push_back
#define mp make_pair

#define maxN 2015
#define maxDef 10
#define compute(x, y) dp[x][y]

int n, i;
char s[maxN];
short dp[maxN][maxN];

short go_r[maxN][maxDef];
short go_l[maxN][maxDef];

int boss;
int l_ind, r_ind;
bool ans[maxN];
bool is_first;

void compute_dp() {
    int i, j;

    for (i = 1; i <= n; i++) dp[i][i] = 1;
    for (int dim = 2; dim <= n; dim++) {
        for (i = n - dim + 1; i > 0; i--) {
            if (s[i] == s[i + dim - 1])
                dp[i][i + dim - 1] = dp[i + 1][i + dim - 2] + 2;
            else
                dp[i][i + dim - 1] = max(dp[i + 1][i + dim - 1], dp[i][i + dim - 2]);
        }
    }
}

/*short compute(int l, int r) {
    if (l > r) return 0;
    if (dp[l][r]) return dp[l][r];

    if (l == r) {
        dp[l][r] = 1;
        return 1;
    }

    dp[l][r] = max(compute(l + 1, r), compute(l, r - 1));
    if (s[l] == s[r]) dp[l][r] = compute(l + 1, r - 1) + 2;

    return dp[l][r];
}*/

int main()
{
    freopen("elimin2.in", "r", stdin);
    freopen("elimin2.out", "w", stdout);

    scanf("%s", s + 1);
    n = strlen(s + 1);

    for (i = 1; i <= n; i++) s[i] = s[i] - '0';

    for (i = 0; i < 10; i++) go_l[0][i] = 0;
    for (i = 1; i <= n; i++) {
        memcpy(go_l[i], go_l[i - 1], sizeof(go_l[i]));
        go_l[i][ s[i] ] = i;
    }

    for (i = 0; i < 10; i++) go_r[n + 1][i] = n + 1;
    for (i = n; i >= 1; i--) {
        memcpy(go_r[i], go_r[i + 1], sizeof(go_r[i]));
        go_r[i][ s[i] ] = i;
    }

    compute_dp();
    boss = compute(1, n);
    l_ind = 1; r_ind = n;
    is_first = true;

    while (boss > 0) {
        bool found = false;

        for (i = 9; i >= 0; i--) {
            if (i == 0 && is_first) continue;

            int xx = go_r[l_ind][i];
            int yy = go_l[r_ind][i];

            if (xx > yy) continue;
            if (compute(xx, yy) != boss) continue;

            found = true;
            ans[xx] = ans[yy] = true;
            l_ind = xx + 1; r_ind = yy - 1;
            break;
        }

        if (found)
            is_first = false;
        boss -= 2;
    }

    for (i = 1; i <= n; i++)
        if (ans[i])
            printf("%c", s[i] + '0');

    return 0;
}