Cod sursa(job #68273)

Utilizator sealTudose Vlad seal Data 27 iunie 2007 13:31:36
Problema Elimin Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include<stdio.h>
#define Nm 7295
#define Mm 16
int M[Nm][Mm],Sl[Nm],Sc[Mm],C[Mm],S[Nm],n,m,r,c,nn,st,sol;

void read()
{
    int i,j;

    freopen("elimin.in","r",stdin);
    scanf("%d%d%d%d",&n,&m,&r,&c);
    for(i=1;i<=n;++i)
        for(j=1;j<=m;++j)
            if(m<=n)
                scanf("%d",&M[i][j]);
            else
                scanf("%d",&M[j][i]);
    if(m>n)
    {
        n=n^m;
        m=n^m;
        n=n^m;
        r=r^c;
        c=r^c;
        r=r^c;
    }
}

int cmp(const void *x, const void *y)
{
    return *(int*)x-*(int*)y;
}

void sink(int i)
{
    int son=i<<1,v=S[i];

    while(son<=n)
    {
        if(son<n && S[son|1]<S[son])
            son|=1;
        if(v<=S[son])
            break;
        S[i]=S[son];
        i=son; son<<=1;
    }
    S[i]=v;
}

void update()
{
    int i,j,s=st;

    for(j=1;j<=c;++j)
        s-=Sc[C[j]];
    for(i=1;i<=n;++i)
    {
        S[i]=Sl[i];
        for(j=1;j<=c;++j)
            S[i]-=M[i][C[j]];
    }
    for(i=n>>1;i;--i)
        sink(i);
    for(i=r;i;--i)
    {
        s-=S[1];
        S[1]=S[n--];
        sink(1);
    }
    if(s>sol)
        sol=s;
    n=nn;
}

void back(int k)
{
    if(k==c+1)
        update();
    else
    {
        int i;

        for(i=C[k-1]+1;i<=m-c+k;++i)
        {
            C[k]=i;
            back(k+1);
        }
    }
}

void solve()
{
    int i,j;

    for(i=1;i<=n;++i)
        for(j=1;j<=m;++j)
        {
            st+=M[i][j];
            Sl[i]+=M[i][j];
            Sc[j]+=M[i][j];
        }
    nn=n;
    back(1);
}

void write()
{
    freopen("elimin.out","w",stdout);
    printf("%d\n",sol);
}

int main()
{
    read();
    solve();
    write();
    return 0;
}