Cod sursa(job #2089967)

Utilizator andreicoman299Coman Andrei andreicoman299 Data 17 decembrie 2017 13:35:57
Problema Elimin 2 Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.2 kb
#include <bits/stdc++.h>
#define MAXN 2001

FILE*fi,*fo;
int v[1 + MAXN];
int 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(d[st][dr], 2 + D(fapp + 1, lapp - 1));
                else
                    d[st][dr] = std::max(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;
}