Cod sursa(job #1501921)

Utilizator akaprosAna Kapros akapros Data 13 octombrie 2015 22:58:18
Problema Elimin 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define maxN 2002
#define maxD 10
using namespace std;
int n, i, j, x, y;
short int dp[maxN][maxN], v[maxN], posi[maxN][maxD], posj[maxN][maxD];
char s[maxN], dig;
void read()
{
    freopen("elimin2.in", "r", stdin);
    gets(s + 1);
    n = strlen(s + 1);
}
vector < char > V;
void solve()
{
    for (dig = 0; dig <= 9; ++ dig)
        for (i = n; i >= 1; -- i)
        {
            if (s[i] == dig + '0')
                posi[i][dig] = i;
            else
                posi[i][dig] = posi[i + 1][dig];
        }
    for (dig = 0; dig <= 9; ++ dig)
        for (i = 1; i <= n; ++ i)
        {
            if (s[i] == dig + '0')
                posj[i][dig] = i;
            else
                posj[i][dig] = posj[i - 1][dig];
        }

    for (i = n; i >= 1; -- i)
        for (j = i + 1; j <= n; ++ j)
        {
            dp[i][i] = 0;
            dp[i][i + 1] = (s[i] != s[i + 1]);
            if (s[i] == s[j])
                dp[i][j] = dp[i + 1][j - 1];
            else
            {
                dp[i][j] = dp[i + 1][j] + 1;
                if (dp[i][j] > dp[i][j - 1] + 1)
                    dp[i][j] = dp[i][j - 1] + 1;
            }
        }
}
void write()
{
    int p = 2 * maxN, d;
    char c = 0;
    freopen("elimin2.out", "w", stdout);
    i = 1;
    j = n;
    for (dig = 9; dig > 0; -- dig)
        if (dp[posi[i][dig]][posj[j][dig]] + posi[i][dig] - posj[j][dig] - i + j < p)
            p = dp[posi[i][dig]][posj[j][dig]] + posi[i][dig] - posj[j][dig] - i + j,
               d = dig;
    i = posi[i][d];
    j = posj[j][d];
    p = p - i + j + 1 - n;
    while (i <= j)
    {
        if((j - i + 1) - p ==1)
        {
            printf("%c", s[i]);
            break;
        }
        V.push_back(s[i]);
        printf("%c", s[i]);
        if ((j - i + 1) - p == 2)
            break;
        for (dig = 9; dig >= 0; -- dig)
            if ((x = posi[i + 1][dig]) <= (y = posj[j - 1][dig]) && dp[posi[i + 1][dig]][posj[j - 1][dig]] + (x - i - 1 + j - y - 1) == p)
                if (x > i && y < j)
            {
                p -= (x - i - 1 + j - y - 1);
                i = x;
                j = y;
                break;
            }
    }
    reverse(V.begin(), V.end());
    for (i = 0; i < V.size(); ++ i)
        printf("%c", V[i]);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}