Cod sursa(job #989632)

Utilizator vendettaSalajan Razvan vendetta Data 26 august 2013 01:27:13
Problema PalM Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

ifstream f("palm.in");
ofstream g("palm.out");

#define nmax 501
#define ll long long
#define pb push_back
#define mp make_pair
#define sz size
#define x first
#define y second

string S;
int n;
int dp[nmax][nmax];
int st[nmax][27];
int dr[nmax][27];

void citeste(){
    getline(f, S);
    n = S.sz();
}

void reindex(){
    string S2; S2 = '$'; for(int i=0; i<(int)S.sz(); ++i) S2 += S[i];
    S = S2;
    //cout << S << "\n";
}

void bagaSt(){
    for(int i=1; i<=n; ++i){
        for(int j='a'-'a'; j<='z'-'a'; ++j){
            st[i][j] = st[i-1][j];
        }
        st[i][ S[i]-'a' ] = i;
    }
}

void bagaDr(){
    for(int i=n; i>=1; --i){
        for(int j='a'-'a'; j<='z'-'a'; ++j){
            dr[i][j] = dr[i+1][j];
        }
        dr[i][ S[i]-'a' ] = i;
    }
}

void rezolva(){
    reindex();
    // e bun si subsirul ... :))( initial credeam ca doar secventa ... )
    // dp[i][j] = cel mai lun sir palindrom munte care are capatele in i respectiv j;
    // dp[i][j] = poate continua litere >= cu a[i]; iau fiecare litera si ii cauat prima apartie la dreapta din pozitia i;
    // respectiv prima aparite la stanga pozitie j;
    bagaSt(); bagaDr();
    int Rez = 1;
    for(int i=1; i<=n; ++i) dp[i][i] = 1;
    //for(int i=1; i<n; ++i) if (S[i] == S[i+1])dp[i][i+1] = 2, Rez = max(Rez, 2);
    for(int i=1; i<=n; ++i){
        for(int j=i+1; j<=n; ++j)
            if (S[i] == S[j]) dp[i][j] = 2;
    }
    //cout << "aici : " << st[7]['a'-'a'] << "\n";
    for(int d=3; d<=n; ++d){
        for(int i=1; i+d-1<=n; ++i){
            int j = i+d-1;
            if (S[i] != S[j]) continue;
            dp[i][j] = 2;
            for(int lit=S[i]-'a'+1; lit<='z'-'a'; ++lit){
                int i2 = dr[i][lit]; int j2 = st[j][lit];
                if (i < i2 && j2 < j) dp[i][j] = max(dp[i][j], dp[i2][j2] + 2);// il extind cu 2
            }
            int i2 = dr[i+1][S[i]-'a']; int j2 = st[j-1][S[i]-'a'];// sa nu ma duca tot in i respectiv in j
            if (i < i2 && j2 < j) dp[i][j] = max(dp[i][j], dp[i2][j2] + 2);// il extind cu 2
            Rez = max(Rez, dp[i][j]);
            //cout << i << " " << j << " " << i2 << " " << j2<< " " << dp[i][j] << "\n";
        }
    }


    g << Rez << "\n";
}

int main(){
    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;
}