Cod sursa(job #112054)

Utilizator stef2nStefan Istrate stef2n Data 2 decembrie 2007 23:09:46
Problema Barman Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
//#define DEBUG

#include <cstdio>
#include <algorithm>
#include <vector>
#ifdef DEBUG
#include <iostream>
#endif
using namespace std;

#define NMAX 600
#define INF 1000000000

int CMIN=INF;
int N, value[NMAX], ind[NMAX];


inline bool cmp(int i, int j)
{
    if(value[i]==value[j])
        return i<j;
    else
        return value[i]<value[j];
}

inline int move(int a, int b)
{
    if(a==b)
        return 0;
    if(a>=N)
        return 20+abs(a-b);
    return 20+min(min(abs(a-b),a+N-b),b+N-a);
}

int mincost(const vector <int> &v, int a, int b)
{
#ifdef DEBUG
    cerr<<"\t";
    for(vector <int> :: const_iterator it=v.begin(); it!=v.end(); ++it)
        cerr<<*it<<" ";
    cerr<<endl;
#endif
    int cost=INF, left=0, right=0;
    for(unsigned int i=0, j=a; i<v.size(); ++i, ++j)
        right+=move(v[i],j);
    for(unsigned int i=0; i<v.size(); ++i)
    {
        if(cost>left+right)
            cost=left+right;
        left+=move(v[i]+N,b-i);
        right=0;
        for(unsigned int k=i+1, j=a; k<v.size(); ++k, ++j)
            right+=move(v[k],j);
    }
    if(cost>left+right)
        cost=left+right;
    return cost;
}


int main()
{
    freopen("barman.in","r",stdin);
    freopen("barman.out","w",stdout);
    scanf("%d",&N);
    for(int i=0; i<N; ++i)
        scanf("%d",&value[i]);
    for(int i=0; i<N; ++i)
    {
        for(int j=0; j<N; ++j)
            ind[j]=j;
        sort(ind, ind+N, cmp);
#ifdef DEBUG
        for(int j=0; j<N; ++j)
            cerr<<ind[j]<<" ";
        cerr<<endl;
#endif

        int cost=0;
        vector <int> v;
        int last=0;
        for(int j=0; j<N; ++j)
            if(!j || value[ind[j]]!=value[ind[j-1]])
            {
                if(j)
                    cost+=mincost(v,last,j-1);
                v.clear();
                v.push_back(ind[j]);
                last=j;
            }
            else
                v.push_back(ind[j]);
        cost+=mincost(v,last,N-1);
        if(CMIN>cost)
            CMIN=cost;

        int tmp=value[0];
        for(int j=0; j<N-1; ++j)
            value[j]=value[j+1];
        value[N-1]=tmp;
    }
    printf("%d\n",CMIN);
    return 0;
}