Cod sursa(job #728849)

Utilizator GheorgheMihaiMihai Gheorghe GheorgheMihai Data 29 martie 2012 00:45:37
Problema Cowfood Scor 18
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.4 kb
#include <stdio.h>

int n, m, s, sol;
int v[22][31];
long long invers[10002], fact[10002];

const int mod = 3210121;

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

void precalc (int x)
{
	int i;
	
	fact[0] = 1;
	for (i = 1; i <= x; i ++)
		fact[i] = fact[i - 1] * i % mod;
	invers[x] = 2268449;
	//for (i = 1; i <= mod - 2; i ++)
	//	invers[x] = invers[x] * fact[x] % mod;
	for (i = x - 1; i >= 0; i --)
		invers[i] = invers[i + 1] * (i + 1) % mod;
}

inline int comb (int a, int b)
{
	return (int) (fact[a] * invers[b] % mod * invers[a - b] % mod);
}

void rez ()
{
	int st, i, lim = (1 << n) - 1, j;
	
	for (st = 1; st <= lim; st ++)
	{
		int nr[31] = {0}, suma = 0, semn = 1;
		
		for (i = 0; i < n; i ++)
			if (st & (1 << i))
			{
				for (j = 1; j <= m; j ++)
					nr[j] = max (nr[j], v[i + 1][j]);
				semn *= -1;
			}
		
		for (j = 1; j <= m; j ++)
			suma += nr[j];
		
		if (suma <= s)
		{
			sol = sol + semn * comb (s - suma + m, m);
			while (sol <= 0)
				sol += mod;
			while (sol >= mod)
				sol -= mod;
		}
	}
}

int main ()
{
	freopen ("cowfood.in", "r", stdin);
	freopen ("cowfood.out", "w", stdout);
	
	scanf ("%d %d %d", &m, &s, &n);
	
	precalc (10000);
	
	int i, j;
	
	for (i = 1; i <= n; i ++)
		for (j = 1; j <= m; j ++)
			scanf ("%d", &v[i][j]);
	
	sol = comb (s, m);
	rez ();
	printf ("%d\n", sol);
	
	return 0;
}