Cod sursa(job #8619)

Utilizator m_dersidanDersidan Mihai m_dersidan Data 25 ianuarie 2007 08:48:50
Problema Elimin Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.65 kb
# include <stdio.h>
# include <string.h>

# define  maxr  20
# define  maxc  7300/15

# define  _fin  "elimin.in"
# define  _fout "elimin.out"


int a[maxr][maxc], n, m, r, c, smin=-1;
int sr[maxr], s;
int sc[maxc];

void readf()
{
	freopen(_fin, "r", stdin);

	scanf("%d %d %d %d", &n, &m, &r, &c);
	int i, j;

	if ( n <= m )	// n <= 15
		for (i=1; i<=n; i++)
			for (j=1; j<=m; j++)
				scanf("%d", &a[i][j]);
	else
	{
		for (i=1; i<=n; i++)
			for (j=1; j<=m; j++)
				scanf("%d", &a[j][i]);

		n ^= m ^= n ^= m;
	}
}
int qspoz(int st, int dr)
{
	int x = sc[st];
	while ( st < dr )
	{
		while ( st<dr && sc[dr]>=x ) dr--; sc[st]=sc[dr];
		while ( st<dr && sc[st]<=x ) st++; sc[dr]=sc[st];
	}
	sc[st]=x; return st;
}
void qs(int st, int dr)
{
	int m = qspoz(st, dr);
	if ( st < m ) qspoz(st, m-1);
	if ( m < dr ) qspoz(m+1, dr);
}
void solve()
{
	int i, j, to, b1, add, k, saux, l;

	for (i=1; i<=n; i++)
		for (j=1; j<=m; sr[i] += a[i][j], sc[j] += a[i][j], s += a[i][j], j++);

	for (i=0, to=(1<<n)-1; i<=to; i++)
	{
		for (j=1, b1=0; j<to; j<<=1)
			if ( i & j ) ++b1;

		if ( b1 == r )	// numarul de randuri excluse
		{
			memset(sc, 0, sizeof(sc));
			saux=s;

			for (j=1, k=1; j<to; j<<=1, k++)
				if ( i & j )
					saux -= sr[k];
				else
				{
					for (l=1; l<=m; l++)
						sc[l] += a[k][l];
				}

			qs(1, m);
			// scot primele cele mai mici c coloane
			for (j=1; j<=c; j++)
				saux -= sc[j];

			if ( saux > smin ) smin = saux;
		}
	}
}

void writef()
{
	freopen(_fout, "w", stdout);
	printf("%d\n", smin);
}

int main()
{
	readf();
	solve();
	writef();

	return 0;
}