Cod sursa(job #36966)

Utilizator MariusMarius Stroe Marius Data 24 martie 2007 13:20:50
Problema Cowfood Scor 18
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 kb
#include <cstdio>
using namespace std;

const char iname[] = "cowfood.in";
const char oname[] = "cowfood.out";

#define MAX_N  20
#define MAX_K  31
#define MAX_S  10001
#define modulo 3210121

int K;
 
int S;

int N;

int A[MAX_N][MAX_K];

int cnt[MAX_K][MAX_S], sum[MAX_K][MAX_S];


void read_in(void)
{
    freopen(iname, "r", stdin);
    int i;
	int j;
	scanf("%d %d", & K, & S);
	for (scanf("%d", & N), i = 0; i < N; ++ i)
		for (j = 0; j < K; ++ j)
			scanf("%d", A[i] + j);
}

int main(void)
{
    read_in();
	/* preprocesare */
	cnt[2][0] = 1;
	for (int j = 1; j <= S; ++ j) {
		cnt[2][j] = j - 1;
		sum[2][j] = (sum[2][j - 1] + cnt[2][j]) % modulo;
	}
	for (int i = 3; i <= K; ++ i) {
		for (int j = 1; j <= S; ++ j) {
			cnt[i][j] = (cnt[i][j - 1] + cnt[i - 1][j]) % modulo;
			sum[i][j] = (sum[i][j - 1] + cnt[i][j]) % modulo;
		}
	}
	int Res = sum[K][S];

	/* solutie : */
	for (int i = 1; i <= K; ++ i) {
		sum[i][0] = cnt[i][0] = 1;
		for (int j = 1; j <= S; ++ j) {
			cnt[i][j] = (cnt[i][j - 1] + cnt[i - 1][j]) % modulo;
			sum[i][j] = (sum[i][j - 1] + cnt[i][j]) % modulo;
		}
	}
	for (int stp = 1; stp < 1 << N; ++ stp) {
		int num = 0;
		for (int i = 0; i < N; ++ i)
			if (stp & 1 << i)	num ++;

		int sub = 0;
		int positive = 0;
		for (int j = 0; j < K; ++ j) {
			int max = 0;
			for (int i = 0; i < N; ++ i) {
				if (stp & 1 << i) 
					if (max < A[i][j])  max = A[i][j];
			}
			sub = sub + max;
			if (max > 0)
				positive ++;
		}
		
		int sgn = (num & 1) ? -1 : +1;
		
		if (positive == 0)
			Res = Res + sgn * K * (K - 1) / 2 * sum[K][S - sub - 2];
		else if (positive == 1)
			Res = Res + sgn * K * sum[K][S - sub - 1];
		else if (positive > 1)
			Res = Res + sgn * sum[K][S - sub];
		
		if (Res < 0)
			Res += modulo;
		else if (Res >= modulo)
			Res -= modulo;
	}
	freopen(oname, "w", stdout);
	printf("%d\n", Res);
	return 0;
}