Cod sursa(job #695220)

Utilizator psycho21rAbabab psycho21r Data 28 februarie 2012 11:19:06
Problema ADN Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int pi[30005], graph[18][18], st, C[18][(1 << 18)], before[18][(1 << 18)], map[18];
bool not_show[18];
string adn[18];
int main()
{
    int n;
    ifstream in("adn.in");
    in >> n;
    for(int i = 0; i < n; ++i)
    {
        in >> adn[i];
    }
    in.close();
    for(int i = 0; i < n; ++i)  //Pi function for i
    {
        int w_size = adn[i].size();
        int back = 0, pos = w_size-3;
        pi[w_size-1] = -1;
        pi[w_size-2] = 0;
        while (pos >= 0)
        {
            if(adn[i][pos+1] == adn[i][w_size-back-1])
            {
                ++back;
                pi[pos] = back;
                --pos;
            }
            else
            if(back > 0)
                back = pi[w_size-back-1];
            else
            {
                pi[pos] = 0;
                --pos;
            }
        }
        for(int j = 0; j < n; ++j) //Make graph
        {
            if(i!=j&&(!not_show[i]))
            {
                int now = 0, pos = 0, w_size = adn[i].size(), s_size = adn[j].size();
                while (now < s_size)
                {
                    if(((adn[i][w_size-1-pos] == adn[j][s_size-1-(now+pos)])&&(now+pos < s_size))||(now+pos >= s_size))
                    {
                        if(pos == w_size-1)
                        {
                            if(now+pos < s_size)
                            {
                                not_show[i] = true; //i is totally included  in j
                                break;
                            }
                            graph[i][j] = s_size - now;
                            break;
                        }
                        else
                            ++pos;
                    }
                    else
                    {
                        now = now + pos - pi[w_size-1-pos];
                        if(pi[w_size-1-pos] > -1)
                            pos = pi[w_size-1-pos];
                        else
                            pos = 0;
                    }
                }
            }
        }
    }
    int Not = 0;
    for(int i = 0; i < n; ++i)
        if(!not_show[i])
            map[Not++] = i;
    for(int i = 1; i < (1<<Not); ++i)
    {
        for(int j = 0; j < Not; ++j)
        {
            if(!(i&(1<<j)))
            {
                C[j][i] = -1;
                for(int k = 0; k < Not; ++k)
                {
                    if(j!=k && ((1<<k)&i))
                    {
                        if(C[k][i-(1<<k)] + graph[map[j]][map[k]] > C[j][i])
                        {
                            C[j][i] = C[k][i-(1<<k)] + graph[map[j]][map[k]];
                            before[j][i] = k;
                        }
                    }
                }
            }
        }
    }
    int max = -1, f, i, k;
    for(int i = 0; i < Not; ++i)
        if(C[i][(1<<Not)-1-(1<<i)] > max)
        {
            max = C[i][(1<<Not)-1-(1<<i)];
            f = i;
        }
    ofstream out("adn.out");
    out << adn[map[f]];
    max = (1<<Not)-1-(1<<f);
    while(max > 0)
    {
        i = before[f][max];
        for(int j = graph[map[f]][map[i]]; j < adn[map[i]].size(); ++j)
            out << adn[map[i]][j];
        max -= (1<<i);
        f = i;
    }
    out.close();
    return 0;
}