Cod sursa(job #237)

Utilizator gcosminGheorghe Cosmin gcosmin Data 7 decembrie 2006 17:35:59
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 kb
#include <stdio.h>

#define SMAX 10010
#define KMAX 32
#define NMAX 22

#define MOD 3210121

inline int MAX(int a, int b) { return (a > b) ? a : b; }


int K, S, N;

int a[NMAX][KMAX];

int din[SMAX][KMAX];
char viz[1 << NMAX];

int jeg[SMAX];

int st[NMAX][KMAX];

int REZ1 = 0;
int REZ2 = 0; 

void make(int x, int nrb, int ant)
{
	viz[x] = 1;

	int s = 0, i;

	if (nrb)
	{
		for (i = 0; i < K; i++) 
		{
			st[nrb][i] = MAX(st[nrb-1][i], a[ant][i]);
			s += st[nrb][i];
		}
	}

//	printf("%d %d %d\n", x, s, din[S - s][K + 1]);
	if (nrb & 1)  { REZ2 += jeg[S - s]; if (REZ2 >= MOD) REZ2 -= MOD; }
	else { REZ1 += jeg[S - s]; if (REZ1 >= MOD) REZ1 -= MOD; }

	int j;
	
	for (i = 0, j = 1; i < N; i++, j <<= 1)
		if (!(j & x) && !viz[j | x])
			make(x | j, nrb + 1, i);
}

int main()
{
	int i, j;
	
	freopen("cowfood.in", "r", stdin);
	freopen("cowfood.out", "w", stdout);

	scanf("%d %d %d\n", &K, &S, &N);

	for (i = 0; i < N; i++)
		for (j = 0; j < K; j++)
			scanf("%d", &a[i][j]);

	for (i = 0; i <= K + 1; i++) din[0][i] = 1;

	jeg[0] = 1;
	for (i = 1; i <= S; i++)
	{
		din[i][1] = 1;
		for (j = 2; j <= K + 1; j++) 
		{
			din[i][j] = din[i-1][j] + din[i][j-1];
			if (din[i][j] >= MOD) din[i][j] -= MOD;
		}
		jeg[i] = din[i][K+1];
	}

	REZ2 = 1;
	if (K > 1) REZ2 += S * K;
	while (REZ2 >= MOD) REZ2 -= MOD;

	make(0, 0, -1);

	// trebuie sa le scad pe alea cu 0

	REZ1 -= REZ2;

	if (REZ1 < 0) REZ1 += MOD;

	printf("%d\n", REZ1);	

fclose(stdin);
fclose(stdout);
return 0;
}