Cod sursa(job #1299422)

Utilizator vladrochianVlad Rochian vladrochian Data 23 decembrie 2014 17:19:49
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.38 kb
#include <fstream>
#include <cstring>
using namespace std;

const int kMaxN = 25, kMaxK = 35, kMaxS = 10105, kMod = 3210121;

ifstream fin("cowfood.in");
ofstream fout("cowfood.out");

int N, K, S, comb[kMaxS][kMaxK], test[kMaxN][kMaxK], lim[kMaxN][kMaxK], sign = 1, sol;

void Read() {
	fin >> K >> S >> N;
	for (int i = 1; i <= N; ++i)
		for (int j = 1; j <= K; ++j)
			fin >> test[i][j];
}

void Comb() {
	comb[0][0] = 1;
	for (int i = 1; i < kMaxS; ++i) {
		comb[i][0] = 1;
		for (int j = 1; j < kMaxK; ++j)
			comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % kMod;
	}
	for (int i = 1; i < kMaxS; ++i)
		for (int j = 0; j < kMaxK; ++j)
			comb[i][j] = (comb[i][j] + comb[i - 1][j]) % kMod;
}

inline int Sol(int sum, int cnt) {
	if (sum < 0)
		return 0;
    return comb[sum + K - 1][K - 1];
}

void Back(int lv, int cnt) {
	for (int crt = 0; crt < 2; ++crt) {
		int nw_cnt = cnt + crt;
		for (int i = 1; i <= K; ++i)
			lim[lv][i] = max(lim[lv - 1][i], crt * test[lv][i]);
		if (lv == N) {
			int s = S;
			for (int i = 1; i <= K; ++i)
				s -= lim[N][i];
			sol = (sol + kMod + Sol(s, nw_cnt) * sign) % kMod;
		} else {
			Back(lv + 1, nw_cnt);
		}
		sign *= -1;
	}
}

int main() {
	Read();
	Comb();
	if (!N)
		sol = comb[S + K - 1][K - 1];
	else
		Back(1, 0);
	sol = (sol + kMod - (K * S + 1) % kMod) % kMod;
	fout << sol << "\n";
	return 0;
}