Cod sursa(job #2273777)

Utilizator NOSCOPEPROKENDYMACHEAMACUMVREAU NOSCOPEPROKENDY Data 31 octombrie 2018 21:54:24
Problema Elimin 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <bits/stdc++.h>

#define MAXN 2001



FILE*fi,*fo;

int v[1 + MAXN];

short d[1 + MAXN][1 + MAXN];

int first[1 + MAXN][10];

int last[2 + MAXN][10];

int D(int st, int dr){

    if(d[st][dr] == -1){

        if(st > dr){

            d[st][dr] = 0;

            return 0;

        }

        if(st == dr){

            d[st][dr] = 1;

            return 1;

        }

        for(int c = 0; c < 10; c++){

            int fapp = first[st][c];

            int lapp = last[dr][c];

            if(fapp <= dr && lapp >= st){

                if(fapp < lapp)

                    d[st][dr] = std::max((int)d[st][dr], 2 + D(fapp + 1, lapp - 1));

                else

                    d[st][dr] = std::max((int)d[st][dr], 1 + D(fapp + 1, lapp - 1));

            }

        }

    }

    return d[st][dr];

}

void Reconstruct(int st, int dr){

    if(st > dr)

        return;

    int maxlen = D(st, dr);

    int c = 9;

    int ok = 0;

    while(!ok){

        int pos = 0;

        int fapp = first[st][c];

        int lapp = last[dr][c];

        if(fapp <= dr && lapp >= st){

            if(fapp < lapp)

                pos = 2 + D(fapp + 1, lapp - 1);

            else

                pos = 1 + D(fapp + 1, lapp - 1);

        }

        if(pos == maxlen){

            ok = 1;

            if(fapp < lapp){

                fputc(c + '0', fo);

                Reconstruct(fapp + 1, lapp - 1);

                fputc(c + '0', fo);

            }

            else

                fputc(c + '0', fo);

        }

        c--;

    }

}



int main(){

    fi=fopen("elimin2.in","r");

    fo=fopen("elimin2.out","w");



    int n = 0;

    char c = fgetc(fi);

    while(isdigit(c)){

        v[++n] = c - '0';

        c = fgetc(fi);

    }



    for(int i = 1; i <= n; i++){

        for(int c = 0; c < 10; c++)

            last[i][c] = last[i - 1][c];

        last[i][v[i]] = i;

    }

    for(int c = 0; c < 10; c++)

        first[n + 1][c] = n + 1;

    for(int i = n; i > 0; i--){

        for(int c = 0; c < 10; c++)

            first[i][c] = first[i + 1][c];

        first[i][v[i]] = i;

    }



    for(int i = 1; i <= n; i++)

        for(int j = 1; j <= n; j++)

            d[i][j] = -1;



    int maxlen = 0;

    for(int c = 1; c < 10; c++){

        int fapp = first[1][c];

        int lapp = last[n][c];

        if(fapp <= n && lapp >= 1){

            if(fapp < lapp)

                maxlen = std::max(maxlen, 2 + D(fapp + 1, lapp - 1));

            else

                maxlen = std::max(maxlen, 1 + D(fapp + 1, lapp - 1));

        }

    }

    c = 9;

    int ok = 0;

    while(!ok){

        int pos = 0;

        int fapp = first[1][c];

        int lapp = last[n][c];

        if(fapp <= n && lapp >= 1){

            if(fapp < lapp)

                pos = 2 + D(fapp + 1, lapp - 1);

            else

                pos = 1 + D(fapp + 1, lapp - 1);

        }

        if(pos == maxlen){

            ok = 1;

            if(fapp < lapp){

                fputc(c + '0', fo);

                Reconstruct(fapp + 1, lapp - 1);

                fputc(c + '0', fo);

            }

            else

                fputc(c + '0', fo);

        }

        c--;

    }

    fclose(fi);

    fclose(fo);

    return 0;

}