Cod sursa(job #1012258)

Utilizator dutzulBodnariuc Dan Alexandru dutzul Data 18 octombrie 2013 16:34:16
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <iostream>
#include <fstream>
using namespace std;

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

#include <cstring>
#define LE 100666
#define LE2 66
#define x first
#define y second
#define pii pair<int,int>
#define mp make_pair
#define inf (1<<30)

string s[LE];
string str;
string result;
int prfx[LE2];
int i,j,t,b[LE2];
int a[LE2][LE2],n2;
bool _incl[LE2];
int dp[LE*5][19],sf;
pii last[LE*4][19];

void precx(int n)
{
    int i,st=0,dr=0;
    for(i=0; i<n; ++i) b[i+1]=str[i];

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

        if (dr>i)
        {
            int pas=prfx[i-st+1];
            _pos=min(dr,st+pas+1);
        }

        if (_pos>=dr)
        {
            bool okz=false;

            for(dr=_pos+1; dr<=n&&okz==false;)
                if (b[dr]!=b[dr-i+1])
                    okz=true;
                else ++dr;

            --dr;
            st=i;
            prfx[i]=dr-i+1;
        }
        else
            prfx[i]=_pos-i+1;
    }
}

int main()
{
    f>>n2;
    f.get();
    for(i=1; i<=n2; ++i) f>>s[i];

    for(i=1; i<=n2; ++i)
        for(j=1; j<=n2; ++j)
            if (i!=j&&_incl[i]==false&&_incl[j]==false)
            {
                str="";
                str+=s[j];
                str+=s[i];
                int n1=s[j].length();
                int N=str.length();

                precx(N);
                a[i][j]=n1;

                for(t=n1+2; t<=N; ++t)
                    if (prfx[t]==n1)
                    {
                        _incl[j]=true;
                        a[i][j]=0;
                        break;
                    }

                for(t=1; t<=N&&_incl[j]==false; ++t)
                {
                    if (prfx[t]+t>N)
                    {
                        a[i][j]=n1-prfx[t];
                        break;
                    }
                }
            }


    //for(i=1; i<=n2; ++i,cout<<'\n')
      //  for(j=1; j<=n2; ++j)
        //    cout<<a[i][j]<<" ";


    for(i=1; i<(1<<n2); ++i)
        for(j=1; j<=n2; ++j) dp[i][j]=inf;

    for(i=1; i<=n2; ++i)
        if (_incl[i]==false)
        {
            sf^=(1<<(i-1));
            dp[1<<(i-1)][i]=s[i].length();
        }

    for(i=1; i<(1<<n2); ++i)
        for(j=1; j<=n2; ++j)
            if (dp[i][j]!=inf)
                for(t=1; t<=n2; ++t)
                {
                    int _bit=(1<<(t-1));

                    if (_incl[t]==false&& (i&_bit)==0)
                        if (dp[i^_bit][t]>dp[i][j]+a[j][t])
                        {
                            dp[i^_bit][t]=dp[i][j]+a[j][t];
                            last[i^_bit][t]=mp(i,j);
                        }
                }

    int res=inf;
    int indn,_plus=0;

    for(i=1; i<=n2; ++i)
        if (dp[sf][i]<res)
        {
            res=dp[sf][i];
            indn=i;
        }

    //cout<<res<<"  "<<indn<<'\n';

    while (sf)
    {
        int N=s[indn].length();

        for(i=N-_plus-1; i>=0; --i)
            result+=(char)s[indn][i];

        pii _sta=last[sf][indn];
        _plus=N-a[_sta.y][indn];

        sf=_sta.x;
        indn=_sta.y;
    }

    int  N=result.size();

    for(i=N-1; i>=0; --i) g<<(char)result[i];

    f.close();
    g.close();
    return 0;
}